(一)、nRF9E5芯片应用简述
nRF9E5是一款工作频率为433/868/915MHz的智能射频芯片,该芯片采用1.9V~3.6V单电源供电,32脚QFN封装(5×5mm),发射功率为10dBm,接收灵敏度-100dBm,在低功耗时电流仅2.5μA,在发射功率为-10dBm时的发射电流11mA,接收模式下的电流12.5mA,适用于工业无线传感器、遥控器和无线报警器等。经测试在没有建筑物阻挡的情况下,发送端放在办公室的桌子上,隔一层玻璃,接收端在1000米远的马路上能稳定传输没问题,或者在本楼层1至4楼之间传输也很好。 下图所示为nRF9E5的内部结构框图。nRF9E5是一片嵌入了nRF905无线收发芯片、集成增强型8051微处理器和4个通道的10位ADC,采样速率为80ksps,内含1.22V电压基准、电源管理、PWM输出、UART异步串口、SPI通讯接口、逻辑接口电路、看门够电路、多通道可编程唤醒,以及CRC检验和多点通信控制,高频电感和滤波器等已经全部内置,外围元件很少,芯片的一致性能好、稳定且不易受干扰。 nRF9E5没有复杂的通讯协议,完全对用户透明,同种产品之间可以自由通讯,内置的CRC纠错硬件电路和协议免去了软件开发人员的软件纠错编程和微控器的纠错运算,降低了无线应用的开发难度。 (二)、nRF9E5芯片I/O口设置 nRF9E5有一8 位的通用双向口(P0口)。另外,4个SPI 也可以用作通用IO口(P1 口)。大部分通用 I/O 口都可以通过编程设置为第二功能,第二功能包括:RXD、TXD,SPI、3个定时器/计数、PWM输出等。 nRF9E5的P0 口通过 P0_ALT 和 P0_DIR 进行设置。若 P0_ALT.n = 1,则引脚P0.n 具有UART、外部中断、定时器输入或脉宽调制输出功能; RXD方向取决于 P0_DIR.1 的值。若要使用 INT0_N 或INT1_N作为中断,则必须使用 P0_ALT.3 / P0_ALT.4 的第二功能。若未置 P0_ALT.n=1,则相应的 P0.n 作为通用 IO 口使用, 其方向由P0_DIR.n 确定。如下表所示:
表9 P0 口功能设置表 P1 口有4 个引脚,当SPI_CTRL=01时是作SPI 口用。。引脚EECSN作为EEPROM 的片选信号,MOSI作为SPI输出,MISO作为SPI输入,SCK作为SPI时钟。将SPI_CTRL设为不等于01时,若P1_ALT.n 设为0则P1.0--P1.3为通用 IO 口,此时 P1_DIR.n 决定是输入还是输出口,见下表。 无线收发器是由 P2 口来控制的,P2口的地址与 8051相同。但是因无线收发器集成在片内,P2口不再是双向口。为了匹配无线电收发器子系统的需要,P2 口锁存电压值与标准8051也有所不同。无线收发器是通过 P2 口特殊功能寄存器的SPI_CTRL 来控制的,如下表所示: SFR 地址 | | | | | | | | | | | NRF905 无线电收发器和AD 转换器子系统的 IO 接口 | | | | | | 00->不用SPI 01->SPI 与端口P1 相连接 1x->SPI 与nRF905/AD相连接 |
P2 寄存器位:功能 | | | | | | | | | | | |
| 2: nRF905收发器和ADC SPI 数据输出(SBMISO) | | |
| |
| | |
| |
| | | | | 3: nRF905收发器和ADC SPI 芯片选择(SBCSN) | | |
| 1: nRF905收发器和ADC SPI 数据 (SBMOSI) | | 0: nRF905收发器和ADC SPI 时钟(SBSCK) | | (三)、nRF9E5芯片A/D口转换
nRF9E5的AD转换器是一个10位的线性转换器,在低频信号及滤波器的作用下可以增大到12位。AD转换器的基准电压是:AREF或内部带隙参考电压(1.22V)。 默认状态下AD 转换器是 10位的,如有特殊要求,也可以设置成6,8,12位转换模式。AD转换器也可以应用在其它模式下,比如 AIN0 输入一负电压,AIN1~AIN3作为放大输入端。 AD 转换器有两个寄存器ADC_CONFIG_REG 和 ADC_DATA_REG。输入频道的选择直接由 START_ADC_CONV 控制,CHSEL 的值从0 到 3 分别对应选择 AIN0 到AIN3, 若CHSEL 设置为 1xxx 则nRF9E5 提供给 AD转换器内部电压:VDD/3~1.22V。 AD 转换的结果将保存在ADC_DATA_REG 寄存器中。数据存储形式如下表所示由ADC_RL_JUST来决定。
溢出状态保存在STATUS_REGISTER寄存器中的 ADC_RFLAG 中。当 ADC_PWR_UP=0时,AD转换器功能被禁止。 使用内部参考电压时的测量值:当VFSSEL=0,CHSEL选择一个输入AINi(AIN0到 AIN3),AD转换的结果 ADCDATA 与 VAINi/1.22成正比:
ADC-配置寄存器说明 参数 | | | | | 当 ADCRUN 无效时,此信号的上升沿将启动AD 转换, | | | 有效时,AD 转换器连续转换。此时可忽视CSTARTN 的状态 | | | | | | AD 转换器参考电压选择 0:内部带隙参考电压(1.22V) 1:外部引脚AREF 参考电压(如果CHSEL=[1xxx],不考虑VFSSEL状态) | | | 输入通道选择: 0000:AIN0 0001: AIN1 0010:AIN2 0011:AIN3 1xxx:内部 VDD/3 | | | A/D 转换器分辨率: 00:6 位 01:8 位 10:10 位 11:12 位 | | | 使能差分测量,AIN0 输入一负电压,AIN1~AIN3 作为放大输入端, | | | 选择向左或者向右数据存放格式 0:数据向左存放 1:数据向右存放 |
状态寄存器说明 参数 | | | | | 地址匹配,接收到与本机地址匹配的地址数据。(见 9.8章) | | | 载波检测,接收到相同频率的载波.详细说明见9.7 章. | | | 数据就绪,接收到一包有效数据(地址和 CRC 校验正确)(见 9.9章) | | | 转换结束,表明 AD 转换已经完成,数据存储在ADC_DATA_REG 里. | | | ADC 溢出标志: RFLAG[2]:未溢出(ADCDATA=0)RFLAG[1]:溢出(ADCDATA=2n-1) RFLAG[0]:溢出部分=RFLAG[1]或者RFLAG[2] |
EXIF 特殊功能寄存器控制字
位 | | | IE5-中断5 标志位。IE5=1 则探测AM 信号上升沿(见P2)。IE5必须由软件清0。使能后软件 设置产生中断 | | IE4-中断4 标志位。IE4=1则探测 DR 信号上升沿.(见P2)。.IE4必须由软件清 0。使能后软件 设置产生中断 | | IE3-中断3 标志位。IE3=1表明内部SPI 模块已发射或接收了 8 位数据,等待新指令。.IE3必 须由软件清 0。使能后软件设置产生中断 | | IE2-中断2 标志位。IE2=1则探测 ADC’s 的EOC 信号上升沿(见第10章)。IE2必须由软件清 0。使能后软件设置产生中断 | | | | |
(四)、nRF9E5芯片用户程序 nRF9E5的主程序存放在外部的串行EEPROM中,当芯片开始上电时,其内部固化的厂家引导程序通过SPI接口,将外部EEPROM中的主程序导入nRF9E5的RAM中(4K字节空间,没有被主程序占用的可作为片内RAM使用),接着执行跳转指令,开始主程序的运行。主程序需要按照下表所示的规则写入EEPROM中,其中SPEED(bit3)为EEPROM的最大读写速度,0为1MHz,1为0.5MHz。XO_FREQ(bit2,1,0)为nRF9E5的外接晶振的频率,000=4MHz,001=8MHz,010=12MHz,011=16MHz,100=20MHz。

在用编程器写程序时,前3个单元是0B0302,后面是主程序。其中0BH=00001011代表speed=1,XO_FREQ =011表示外接晶振是16MHz,03代表应用程序起始偏移量,02代表主程序的256字节区,见下图。
nRF9E5发送数据程序 ;开机进行键扫描,有按键按下,就把该键值(10h,20h,40h)送出20个,然后等待接收20个字符;接收到20个字符后,把这些数据送串口发送到微机里,用串口调试助手可以检查接收情况。
PWMCON EQU 0A9h
PWMDUTY EQU 0AAh
REGX_MSB EQU 0ABh
REGX_LSB EQU 0ACh
REGX_CTRL EQU 0ADh
RSTREAS EQU 0B1h
SPI_DATA EQU 0B2h
SPI_CTRL EQU 0B3h
SPICLK EQU 0B4h
TICK_DV EQU 0B5h
CK_CTRL EQU 0B6h
CKLFCON EQU 0BFh
EXIF EQU 91h
EIE EQU0E8h
CKCON EQU 8EH
SPI_SCK EQU P2.0
SPI_MOSI EQU P2.1
RACSN EQU P2.3
TXEN EQU P2.4
TRX_CE EQU P2.5
SPI_MISO EQU P2.2
EOC EQU P2.4
DR EQU P2.5
CD EQU P2.6
AM EQU P2.7
P0_DRV EQU93H
P0_DIR EQU 94H
P0_ALT EQU 95H
P1_DIR EQU 96H
P1_ALT EQU 97H
KeyValue EQU 20H
L0 EQU KeyValue.4 ;L0=1,(20H)=10H
L1 EQU KeyValue.5 ;L1=1,(20H)=20H
L2 EQU KeyValue.6 ;L2=1,(20H)=40H
S0 EQU P0.5
S1 EQU P0.6
S2 EQU P0.7
LED0 EQU P0.0
LED1 EQU P0.3
LED2 EQU P0.4
BZW EQU 12H ;设一个标志位
ORG 0000H
LJMP MAIN
ORG 000BH
RETI
ORG 0013H
RETI
ORG 001BH
RETI
ORG 0023H
RETI
ORG004BH
RETI
ORG 0050H
;串口发送数据到pc
PutChar: CLR ES
MOV SBUF ,R7
JNB TI, $ ;串口发送无线收到的R7键值(10H,20H,40H)
CLR TI
SETB ES
RET
;初始化子程序
Init: MOV SP,#60H ;设堆栈指针
MOV TH1,#0F3h ;波特率19200,N,8,1
MOV TL1,#0F3h ;波特率19200,N,8,1 ;;;;;;
ORL CKCON,#10H ;T1M=1,1/4时钟
MOV PCON,#80H ;SMOD=1,波特率加倍
MOV SCON,# 50h ; Timer1 8bit auto reload ,方式1,REN=1,TI=1
MOV TMOD,#21h ;
SETB TR1 ;启动定时器1
ORL P0_ALT,#06h ; P0.0 out,P0.1 input(RXD),P0.2(TXD) P0.3P0.4输出,,P0.5 P0.6 P0.7输入
MOV P0_DIR,#0E2h
MOV SPICLK,#01h ; Connect internal SPI controller toRadio
MOV SPI_CTRL,#02h
SETB LED0 ;灯灭
SETB LED1
SETB LED2
MOV BZW,#00H
CLR RACSN ;SPI片选有效
MOV R7,#19h ;读RF配置寄存器10-19为读命令
LCALL SpiReadWrite
CLR A
MOV R7,A
LCALL SpiReadWrite
MOV A,R7
ORL A,#0CH ;读结果送R6也就是送到06H单元
MOV R6,A
SETB RACSN
CLR RACSN
MOV R7,#09h ;00-09写RF配置寄存器命令
LCALL SpiReadWrite
MOV R7,06h
LCALL SpiReadWrite ;把读出的结果写回
SETB RACSN
CLR RACSN ; Write to RF config address 3 (RX payload)
MOV R7,#03H ;配置RX_PWR,初值20H,32个字节03h是3个字节
LCALL SpiReadWrite
MOV R7,# 01h
LCALL SpiReadWrite
MOV R7,# 01h
LCALL SpiReadWrite
SETB RACSN
CLR RACSN
MOV R7,#11h ;Read RF config address 1
LCALL SpiReadWrite ;读配置寄存器。0001aaaa,aaaa指出读操作的开始字节,
CLR A ;字节数量取决于aaaa指出的开始地址。
MOV R7,A
LCALL SpiReadWrite ;写配置寄存器。0000aaaa,aaaa指出写操作的开始字节,
MOV A,R7 ; 字节数量取决于aaaa指出的开始地址.
ANL A,#0F0H
MOV R6,A
SETB RACSN
CLR RACSN ; Write RF config address 0
CLR A
MOV R7,A
LCALL SpiReadWrite
MOV R7,#05Fh
LCALL SpiReadWrite
MOV A,R6
ORL A,#0Dh
MOV R7,A
LCALL SpiReadWrite
MOV R7,#44h ;44接收、发送地址长度
LCALL SpiReadWrite
MOV R7,#01H ;01h为1字节有效20h是32字节有效
LCALL SpiReadWrite
MOV R7,#01h
LCALL C0185
SETB RACSN
SETB EA
SETB ES ;
RET
;扫描键盘子程序
ScanKey: CLR A ;扫描键盘即扫描3个按钮,获取键值
MOV KeyValue,A ;没有键盘按下转c00b1
JB S0,C00B1
SETB L0 ;L0按下Keyvalue=10h,L0=Keyvalue.4
CLR LED0 ;1键盘按下LED0灯亮延时后熄灭
MOV R7,#1AH
LCALL Delayms
SETB LED0
C00B1:JB S1,C00BF ;L1按下Keyvalue=20h,L0=Keyvalue.5
SETB L1
CLR LED1
MOV R7,#1AH
LCALL Delayms
SETB LED1
C00BF:JB S2 ,C00CD
SETB L2 ;L2按下Keyvalue=40h,L0=Keyvalue.6
CLR LED2
MOV R7,#1AH
LCALL Delayms
SETB LED2
C00CD: MOV A,KeyValue
JZ C00D9
FS: MOV R2,#20H ;发送20个字节
FS1: MOV A,KeyValue
MOV R7,A ;获取的键值送R7
SETB TXEN ;发送使能
LCALL TransmitPacket ;调用发射程序包
CLR TXEN
MOV R7,#2AH
LCALL Delay100us
DJNZ R2,FS1
C00D9: RET
;无线接收子程序
ReceivePacket: SETB TRX_CE ;等待接收完毕
JNB TRX_CE,C010E
CLR RACSN
MOV R7,#24H ;读接收数据命令
LCALL SpiReadWrite
CLR A
MOV R7,A
LCALL SpiReadWrite
SETB RACSN
CLR TRX_CE
MOV KeyValue,R7
INC BZW
JNB L0,C00F9 ;对接收数据进行计数
CLR LED0 C00F9: JNB L1,C00FE
CLR LED1
C00FE: JNB L2,C0103
CLR LED2
C0103: MOV R7,#0AH
LCALL Delayms
SETB LED0
SETB LED1
SETB LED2
C010E: RET
;无线发送子程序
TransmitPacket: MOV R5,07H ; Spi enable for write a spi command
CLR RACSN ;Writeaddress command
MOV R7,#22H ;写发送地址命令22H
LCALL C0185 ;E7,E7,E7,E7 TX_ADDRESS
SETB RACSN
MOV R7,#01H ;延时100微秒
LCALL Delay100us
CLR RACSN
MOV R7,#20H ;写发送数据命令20H
LCALL SpiReadWrite
MOV R7,05H ;保存在R5中的键值送R7发送
LCALL SpiReadWrite
SETB RACSN
SETB TRX_CE
MOV R7,#0AH ;发送后延时
LCALL Delay100us
CLR TRX_CE
C0136: JNB TRX_CE,C0136 ;等待发送完毕
RET
;主程序
main: LCALL Init ;主程序,现调用初始化程序
CLR LED0 ;3个灯陆续点亮后熄灭
MOV R7,#0AH
LCALL Delayms
CLR LED1
MOV R7,#0AH
LCALL Delayms
CLR LED2
MOV R7,#0AH
LCALL Delayms
SETB LED0
SETB LED1
SETB LED2
Q: MOVA,#20H
MOVR2,#60D ;清数据区
MOV R0,#13H
QING: MOV@R0,A ;清数据区
INC R0
DJNZ R2,QING
C0158: LCALL ScanKey ;扫描键盘等待接受数据
MOV A,KeyValue
JZ C0158
MOV R0,#30H
AJMPFH ;等待接收数据
CLR A ;扫描键盘即扫描3个按钮,获取键值
MOV KeyValue,A ;没有键盘按下转c00b1
JB S0,C0158
SETB L0 ;L0按下Keyvalue=10h,L0=Keyvalue.4
CLR LED0 ;1键盘按下LED0灯亮延时后熄灭
MOV R7,#0AH
LCALL Delayms
SETB LED0
MOV A,KeyValue
JZ C0158
FH: SETB TRX_CE ; nRF905 收发器使能,接收器功能
JNB TRX_CE,FH
CLR RACSN
MOV R7,#24H ;读接收数据命令
LCALL SpiReadWrite
CLR A
MOV R7,A
LCALL SpiReadWrite
SETB RACSN ;SPI片选有效
CLR TRX_CE
MOV A,R7
MOV @R0,A
MOV R7,#05H ;延时100微秒
LCALL Delay100us
INC BZW
INC R0
MOV A,BZW
XRL A,#20D
JZ FH0
AJMP FH
FH0: MOVR2,#20D ; OK
MOV R0,#30H
CLR LED0
FH1: MOV A,@R0
MOV R7,A
LCALL PutChar
INC R0
DJNZ R2,FH1
LCALL Delay
MOV BZW,#0
SETB LED0
LCALL Delay
LJMP C0158
C0185: LCALL SpiReadWrite ;写发送数据地址
MOV R7,#0E7H
LCALL SpiReadWrite
MOV R7,#0E7H
LCALL SpiReadWrite
MOV R7,#0E7H
LCALL SpiReadWrite
MOV R7,#0E7H
SpiReadWrite: ANL EXIF,#0DFH ;Move byte to send to SPI data register
MOV SPI_DATA,R7 ;读写SPI数据
C019E: MOV A,EXIF
JNB 0E0H.5,C019E
MOV R7,SPI_DATA
RET
Delayms: MOV 10H,R7 ;延时子程序
C01A8: MOV R7, 10H
DEC 10H
MOV A,R7
JZ C01BF
CLR A
MOV R5,A
C01B1: MOV A,R5
CLR C
SUBB A,#0AH
JNC C01A8
MOV R7,#0AH
LCALL Delay100us
INC R5
SJMP C01B1
C01BF: RET
Delay100us: MOV 11H,R7
Delay100us1: MOV R7, 11H
DEC 11H
MOV A,R7
JZ C021D
CLR A
MOV R6,A
Delay100us2: MOV A,R6
CLR C
SUBB A,#23H
JNC Delay100us1
INC R6
SJMP Delay100us2
C021D: RET
DELAY: MOV 70H,#0FFH
DELAY1: LCALL DELAY2
DJNZ 70H,DELAY1
RET
DELAY2: MOV 71H,#0FFH
DELAY3: NOP
DJNZ 71H,DELAY3
RET
END
nRF9E5接收数据程序示例 ;开机等待接收20个字符,送到30h起始的单元中,然后再把这些数据发送出去
PWMCON EQU 0A9h
PWMDUTY EQU 0AAh
REGX_MSB EQU 0ABh
REGX_LSB EQU 0ACh
REGX_CTRL EQU 0ADh
RSTREAS EQU 0B1h
SPI_DATA EQU 0B2h
SPI_CTRL EQU 0B3h
SPICLK EQU 0B4h
TICK_DV EQU 0B5h
CK_CTRL EQU 0B6h
CKLFCON EQU 0BFh
EXIF EQU 91h
EIE EQU 0E8h
CKCON EQU 8EH
SPI_SCK EQU P2.0
SPI_MOSI EQU P2.1
RACSN EQU P2.3
TXEN EQU P2.4
TRX_CE EQU P2.5
SPI_MISO EQU P2.2
EOC EQU P2.4
DR EQU P2.5
CD EQU P2.6
AM EQU P2.7
P0_DRV EQU93H
P0_DIR EQU 94H
P0_ALT EQU 95H
P1_DIR EQU 96H
P1_ALT EQU 97H
KeyValue EQU 20H
L0 EQU KeyValue.4 ;L0=1,(20H)=10H
L1 EQU KeyValue.5 ;L1=1,(20H)=20H
L2 EQU KeyValue.6 ;L2=1,(20H)=40H
S0 EQU P0.5
S1 EQU P0.6
S2 EQU P0.7
LED0 EQU P0.0
LED1 EQU P0.3
LED2 EQU P0.4
BZW EQU 12H ;设一个标志位
ORG0000H
LJMP MAIN
ORG 000BH
RETI
ORG 0013H
RETI
ORG 001BH
RETI
ORG 0023H
RETI
ORG 004BH
RETI
ORG 0050H
PutChar: CLR ES
MOV SBUF ,R7
JNB TI, $ ;串口发送无线收到的R7键值(10H,20H,40H)
CLR TI
SETB ES
RET
Init: MOV SP,#60H ;设堆栈指针
MOV TH1,#0F3h ;波特率19200,N,8,1
MOV TL1,#0F3h ;波特率19200,N,8,1 ;;;;;;
ORL CKCON,#10H ;T1M=1,1/4时钟
MOV PCON,#80H ;SMOD=1,波特率加倍
MOV SCON,# 50h ; Timer1 8bit auto reload ,方式1,10位UART波特率可变,波特率受MSOD影响,REN=1,TI=1
MOV TMOD,#21h ; Timer1 8bit auto reload 20---21;;;;;;
SETB TR1 ;启动定时器1
ORL P0_ALT,#06h ; P0.0 out,P0.1 input(RXD),P0.2(TXD) P0.3 P0.4输出,,P0.5 P0.6P0.7输入
MOV P0_DIR,#0E2h
MOV SPICLK,#01h ; Connect internal SPI controller to Radio
MOV SPI_CTRL,#02h
SETB LED0 ;灯灭
SETB LED1
SETB LED2
MOV BZW,#00H
CLR RACSN ;SPI片选有效
MOV R7,#19h ;读RF配置寄存器10-19为读命令
LCALL SpiReadWrite
CLR A
MOV R7,A
LCALL SpiReadWrite
MOV A,R7
ORL A,#0CH ;读结果送R6也就是送到06H单元
MOV R6,A
SETB RACSN
CLR RACSN
MOV R7,#09h ;00-09写RF配置寄存器命令
LCALL SpiReadWrite
MOV R7,06h
LCALL SpiReadWrite ;把读出的结果写回
SETB RACSN
CLR RACSN ; Write to RF config address 3 (RX payload)
MOV R7,#03H ;配置RX_PWR,初值20H,32个字节01h是1个字节
LCALL SpiReadWrite
MOV R7,# 01h
LCALL SpiReadWrite
MOV R7,# 01h
LCALL SpiReadWrite
SETB RACSN
CLR RACSN
MOV R7,#11h ;Read RF config address 1
LCALL SpiReadWrite ;读配置寄存器。0001aaaa,aaaa指出读操作的开始字节,
CLR A ;字节数量取决于aaaa指出的开始地址。
MOV R7,A
LCALL SpiReadWrite ;写配置寄存器。0000aaaa,aaaa指出写操作的开始字节,
MOV A,R7 ;字节数量取决于aaaa指出的开始地址.
ANL A,#0F0H
MOV R6,A
SETB RACSN
CLR RACSN ; Write RF config address 0
CLR A
MOV R7,A
LCALL SpiReadWrite
MOV R7,#05Fh
LCALL SpiReadWrite
MOV A,R6
ORL A,#0Dh
MOV R7,A
LCALL SpiReadWrite
MOV R7,#44h ;44接收、发送地址长度
LCALL SpiReadWrite
MOV R7,#01H ;01h为1字节有效20h是32字节有效
LCALL SpiReadWrite
MOV R7,#01h
LCALL C0185
SETB RACSN
SETB EA
SETB ES ;
RET
ScanKey: CLR A ;扫描键盘即扫描3个按钮,获取键值
MOV KeyValue,A ;没有键盘按下转c00b1
JB S0,C00B1
SETB L0 ;L0按下Keyvalue=10h,L0=Keyvalue.4
CLR LED0 ;1键盘按下LED0灯亮延时后熄灭
MOV R7,#0AH
LCALL Delayms
SETB LED0
C00B1: JB S1,C00BF ;L1按下Keyvalue=20h,L0=Keyvalue.5
SETB L1
CLR LED1
MOV R7,#0AH
LCALL Delayms
SETB LED1
C00BF: JB S2 ,C00CD
SETB L2 ;L2按下Keyvalue=40h,L0=Keyvalue.6
CLR LED2
MOV R7,#0AH
LCALL Delayms
SETB LED2
C00CD: MOV A,KeyValue
JZ C00D9
FS: SETB TXEN ;发送使能
MOV R7,A ;获取的键值送R7
MOV R2,#20H ;发送20个字节
FS1: LCALL TransmitPacket ;调用发射程序包
DJNZ R2,FS1
CLR TXEN
C00D9: RET
ReceivePacket: SETB TRX_CE ;等待接收完毕
JNB TRX_CE,C010E
CLR RACSN
MOV R7,#24H ;读接收数据命令
LCALL SpiReadWrite
CLR A
MOV R7,A
LCALL SpiReadWrite
SETB RACSN
CLR TRX_CE
MOV KeyValue,R7
INC BZW
JNB L0,C00F9 ;对接收数据进行计数
CLR LED0 C00F9: JNB L1,C00FE
CLR LED1
C00FE: JNB L2,C0103
CLR LED2
C0103: MOV R7,#0AH
LCALL Delayms
SETB LED0
SETB LED1
SETB LED2
C010E: RET
TransmitPacket:MOV R5,07H ; Spi enable for write a spi command
CLR RACSN ;Writeaddress command
MOV R7,#22H ;写发送地址命令22H
LCALL C0185 ;E7,E7,E7,E7 TX_ADDRESS
SETB RACSN
MOV R7,#01H ;延时100微秒
LCALL Delay100us
CLR RACSN
MOV R7,#20H ;写发送数据命令20H
LCALL SpiReadWrite
MOV R7,05H ;保存在R5中的键值送R7发送
LCALL SpiReadWrite
SETB RACSN
SETB TRX_CE
MOV R7,#0AH ;发送后延时
LCALL Delay100us
CLR TRX_CE
C0136: JNB TRX_CE,C0136 ;等待发送完毕
RET
main: LCALL Init ;主程序,现调用初始化程序
CLR LED0 ;3个灯陆续点亮后熄灭
MOV R7,#0AH
LCALL Delayms
CLR LED1
MOV R7,#0AH
LCALL Delayms
CLR LED2
MOV R7,#0AH
LCALL Delayms
SETB LED0
SETB LED1
SETB LED2
C0158: LCALL ScanKey ;扫描键盘等待接受数据
Q: MOVA,#20H
MOVR2,#60D ;清数据区
MOV R0,#13H
QING: MOV@R0,A ;清数据区
INC R0
DJNZ R2,QING
MOV R0,#30H
MOV R2,#20D
AJMPFH ;等待接收数据
FCBQ1: MOV R0,#30H
MOV R2,#20D
FCBQ2: MOV A,@R0
SETB TXEN ;发送使能
MOV R7,A ;获取的键值送R7
LCALL TransmitPacket ;调用发射程序包
CLR TXEN
MOV R7,#0AH ;必须加延时,否则收不到
LCALL Delay100us
INC R0
DJNZ R2,FCBQ2
CLR LED0
LCALL Delay
SETB LED0
MOV BZW,#0
LJMP C0158
FH: MOV R0,#30H
JS0: SETB TRX_CE ;等待接收完毕
JNB TRX_CE,JS0
CLR RACSN
MOV R7,#24H ;读接收数据命令
LCALL SpiReadWrite
CLR A
MOV R7,A
LCALL SpiReadWrite
SETB RACSN
CLR TRX_CE
MOV A,R7
MOV @R0,A
XRL A,#10H
JNZ JS1
CLR LED0 ;;;;;;
AJMP JS3
JS1: MOV A,R7
XRLA,#20H
JNZ JS2
CLR LED1 ;;;;;;
JS2: MOV A,R7
XRL A,#40H
JNZ JS3
CLR LED2 ;;;;;;
JS3: MOV R7,#0AH ;延时100微秒
LCALL Delay100us
INC BZW
INC R0
MOV A,BZW
XRL A,#20D
JZ FH2
AJMP JS0
FH0: MOV R2,#20D
MOV R0,#30H
FH1: MOV A,@R0
MOV R7,A
LCALL PutChar
INC R0
DJNZ R2,FH1
LCALL Delay
MOV BZW,#0
SETB LED0
FH2: LCALL Delay
LCALL Delay
LCALL Delay
LCALL Delay
SETB LED0
SETB LED1
SETB LED2
LJMP FCBQ1
C0185: LCALL SpiReadWrite ;写发送数据地址
MOV R7,#0E7H
LCALL SpiReadWrite
MOV R7,#0E7H
LCALL SpiReadWrite
MOV R7,#0E7H
LCALL SpiReadWrite
MOV R7,#0E7H
SpiReadWrite: ANL EXIF,#0DFH ;Move byte to send to SPI data register
MOV SPI_DATA,R7 ;读写SPI数据
C019E: MOV A,EXIF
JNB 0E0H.5,C019E
MOV R7,SPI_DATA
RET
Delayms: MOV 10H,R7 ;延时子程序
C01A8: MOV R7, 10H
DEC 10H
MOV A,R7
JZ C01BF
CLR A
MOV R5,A
C01B1: MOV A,R5
CLR C
SUBB A,#0AH
JNC C01A8
MOV R7,#0AH
LCALL Delay100us
INC R5
SJMP C01B1
C01BF: RET
Delay100us: MOV 11H,R7
Delay100us1: MOV R7, 11H
DEC 11H
MOV A,R7
JZ C021D
CLR A
MOV R6,A
Delay100us2: MOV A,R6
CLR C
SUBB A,#23H
JNC Delay100us1
INC R6
SJMP Delay100us2
C021D: RET
DELAY: MOV70H,#0FFH
DELAY1: LCALL DELAY2
DJNZ70H,DELAY1
RET
DELAY2: MOV 71H,#0FFH
DELAY3: NOP
DJNZ71H,DELAY3
RET
END
nRF9E5A/D转换程序(无线温度计程序)
;开机定时器工作35h为0时,a/d转换采集20个数据后,无线发送40h单元开始的20个数据。
PWMCON EQU 0A9h
PWMDUTY EQU 0AAh
REGX_MSB EQU 0ABh
REGX_LSB EQU 0ACh
REGX_CTRL EQU 0ADh
RSTREAS EQU 0B1h
SPI_DATA EQU 0B2h
SPI_CTRL EQU 0B3h
SPICLK EQU 0B4h
TICK_DV EQU 0B5h
CK_CTRL EQU 0B6h
CKLFCON EQU 0BFh
EXIF EQU 91h
EIE EQU 0E8h
CKCON EQU 8EH
SPI_SCK EQU P2.0
SPI_MOSI EQU P2.1
RACSN EQU P2.3
TXEN EQU P2.4
TRX_CE EQU P2.5
SPI_MISO EQU P2.2
EOC EQU P2.4
DR EQU P2.5
CD EQU P2.6
AM EQU P2.7
P0_DRV EQU93H
P0_DIR EQU 94H
P0_ALT EQU 95H
P1_DIR EQU 96H
P1_ALT EQU 97H
KeyValue EQU 20H
L0 EQU KeyValue.4 ;L0=1,(20H)=10H
L1 EQU KeyValue.5 ;L1=1,(20H)=20H
L2 EQU KeyValue.6 ;L2=1,(20H)=40H
S0 EQU P0.5
S1 EQU P0.6
S2 EQU P0.7
LED0 EQU P0.0
LED1 EQU P0.3
LED2 EQU P0.4
BZW EQU 12H ;设一个标志位
ORG 0000H
LJMP MAIN
ORG 000BH
LJMP C1
ORG 0013H
RETI
ORG 001BH
RETI
ORG 0023H
RETI
ORG 004BH
RETI
ORG 0050H
C1: CPLLED0
MOV TH0,#0BH
MOV TL0, #06H
INC 2FH
MOV A,2FH
CJNE A, #32H, C2
MOV 2FH, #00H
INC 35H ;秒个位加1
MOV A,35H
CJNE A, #0AH, C2
MOV 35H, #00H
INC 34H ;秒十位加1
MOV A,34H;
C2: RETI
PutChar: PUSH ACC
CLR ES
MOV SBUF ,R7
JNB TI, $ ;串口发送无线收到的R7键值(10H,20H,40H)
CLR TI
SETB ES
POP ACC
RET
JSSJ: CLR EIE.1 ;INT3中断使能位,禁止中断
CLR LED1
INCBZW
MOVA,EXIF ;EXIF.5INT3中断标志位
JNB ACC.5 ,$ ;串口发送无线收到的R7键值(10H,20H,40H)
SETB ACC.5
MOV EXIF,A
SETBEIE.1 ;INT3中断使能,即允许中断
RETI
Init: MOV SP,#60H ;设堆栈指针
MOV TH1,#0F3h ;波特率19200,N,8,1
; MOV TL1,#0F3h ;波特率19200,N,8,1 ;;;;;;
MOV TH0, #3CH
MOV TL0, #0c0h;
ORL CKCON,#10H ;T1M=1,1/4时钟
MOV PCON,#80H ;SMOD=1,波特率加倍
MOV SCON,# 50h ; Timer1 8bit auto reload ,方式1,10位UART波特率可变,波特率受MSOD影响,REN=1,TI=1
MOV TMOD,#21h ; Timer1 8bit auto reload 20---21;;;;;;
SETB TR1 ;启动定时器1
ORL P0_ALT,#06h ; P0.0 out,P0.1 input(RXD),P0.2(TXD) P0.3 P0.4输出,,P0.5 P0.6P0.7输入
MOV P0_DIR,#0E2h
MOV SPICLK,#01h ; Connect internal SPI controller to Radio
MOV SPI_CTRL,#02H;02h
SETB LED0 ;灯灭
SETB LED1
SETB LED2
MOV BZW,#00H
CLR RACSN ;SPI片选有效
MOV R7,#19h ;读RF配置寄存器10-19为读命令
LCALL SpiReadWrite
CLR A
MOV R7,A
LCALL SpiReadWrite
MOV A,R7
ORL A,#0CH ;读结果送R6也就是送到06H单元
MOV R6,A
SETB RACSN
CLR RACSN
MOV R7,#09h ;00-09写RF配置寄存器命令
LCALL SpiReadWrite
MOV R7,06h
LCALL SpiReadWrite ;把读出的结果写回
SETB RACSN
CLR RACSN ; Write to RF config address 3 (RX payload)
MOV R7,#03H ;配置RX_PWR,初值20H,32个字节01h是1个字节
LCALL SpiReadWrite
MOV R7,# 01h
LCALL SpiReadWrite
MOV R7,# 01h
LCALL SpiReadWrite
SETB RACSN
CLR RACSN
MOV R7,#11h ;Read RF config address 1
LCALL SpiReadWrite ;读配置寄存器。0001aaaa,aaaa指出读操作的开始字节,
CLR A ;字节数量取决于aaaa指出的开始地址。
MOV R7,A
LCALL SpiReadWrite ;写配置寄存器。0000aaaa,aaaa指出写操作的开始字节,
MOV A,R7 ; 字节数量取决于aaaa指出的开始地址.
ANL A,#0F0H
MOV R6,A
SETB RACSN
CLR RACSN ; Write RF config address 0
CLR A
MOV R7,A
LCALL SpiReadWrite
MOV R7,#05Fh
LCALL SpiReadWrite
MOV A,R6
ORL A,#0Dh
MOV R7,A
LCALL SpiReadWrite
MOV R7,#44h ;44接收、发送地址长度
LCALL SpiReadWrite
MOV R7,#01H ;01h为1字节有效20h是32字节有效
LCALL SpiReadWrite
MOV R7,#01h
LCALL C0185
SETB RACSN
InitADC: CLR RACSN ;Configure and turn on ADC
MOV R7,#44h
LCALL SpiReadWrite
MOV R7,#35H ;Select AIN3, PWR_UP = 1, VFSEL=0;
LCALL SpiReadWrite
MOV R7,#09H;0BH ;Set RES_CTRL = 3, 11位,Rightjustified
LCALL SpiReadWrite
SETB RACSN
SETB EA
SETB ES ;EA, ES, EX1, ET0, EX0;;;;;;
SETB ET0
SETB 0BCH ;通信中断优先,IP中PS置1
RET
ScanKey: CLR A ;扫描键盘即扫描3个按钮,获取键值
MOV KeyValue,A ;没有键盘按下转c00b1
JB S0,C00B1
SETB L0 ;L0按下Keyvalue=10h,L0=Keyvalue.4
CLR LED0 ;1键盘按下LED0灯亮延时后熄灭
MOV R7,#1AH
LCALL Delayms
SETB LED0
C00B1: JB S1,C00BF ;L1按下Keyvalue=20h,L0=Keyvalue.5
SETB L1
CLR LED1
MOV R7,#1AH
LCALL Delayms
SETB LED1
C00BF: JB S2 ,C00CD
SETB L2 ;L2按下Keyvalue=40h,L0=Keyvalue.6
CLR LED2
MOV R7,#1AH
LCALL Delayms
SETB LED2
C00CD: MOV A,KeyValue
JZ C00D9
FS: MOV R2,#20H ;发送20个字节
FS1: MOV A,KeyValue
MOV R7,A ;获取的键值送R7
SETB TXEN ;发送使能
LCALL TransmitPacket ;调用发射程序包
CLR TXEN
MOV R7,#2AH
LCALL Delay100us
DJNZ R2,FS1
C00D9: RET
ReceivePacket: SETB TRX_CE ;等待接收完毕
JNB TRX_CE,C010E
CLR RACSN
MOV R7,#24H ;读接收数据命令
LCALL SpiReadWrite
CLR A
MOV R7,A
LCALL SpiReadWrite
SETB RACSN
CLR TRX_CE
MOV KeyValue,R7
INC BZW
JNB L0,C00F9 ;对接收数据进行计数
CLR LED0
C00F9: JNB L1,C00FE
CLR LED1
C00FE: JNB L2,C0103
CLR LED2
C0103: MOV R7,#0AH
LCALL Delayms
SETB LED0
SETB LED1
SETB LED2
C010E: RET
TransmitPacket:MOV R5,07H ; Spi enable for write a spi command
CLR RACSN ;Writeaddress command
MOV R7,#22H ;写发送地址命令22H
LCALL C0185 ;E7,E7,E7,E7 TX_ADDRESS
SETB RACSN
MOV R7,#01H ;延时100微秒
LCALL Delay100us
CLR RACSN
MOV R7,#20H ;写发送数据命令20H
LCALL SpiReadWrite
MOV R7,05H ;保存在R5中的键值送R7发送
LCALL SpiReadWrite
SETB RACSN
SETB TRX_CE
MOV R7,#0AH ;发送后延时
LCALL Delay100us
CLR TRX_CE
C0136: JNB TRX_CE,C0136 ;等待发送完毕
RET
main: LCALL Init ;主程序,现调用初始化程序
CLR LED0 ;3个灯陆续点亮后熄灭
MOV R7,#0AH
LCALL Delayms
CLR LED1
MOV R7,#0AH
LCALL Delayms
CLR LED2
MOV R7,#0AH
LCALL Delayms
SETB LED0
SETB LED1
SETB LED2
Q: MOV A,#0H
MOVR2,#60D ;清数据区
MOV R0,#12H
QING: MOV@R0,A ;清数据区
INC R0
DJNZ R2,QING
SETB TR0
C0158: SETB TR0;
MOV A,35H
CJNE A, #0AH, C0158
CLR TR0
LCALL StartADC
MOV A,40H
MOV R7,A
CPL LED1
CLR TR0
FCBQ1: MOV R0,#40H
MOV R2,#20D
FCBQ2: MOV A,@R0
SETB TXEN ;发送使能
MOV R7,A ;获取的键值送R7
LCALL TransmitPacket ;调用发射程序包
CLR TXEN
MOV R7,#0AH ;必须加延时,否则收不到
LCALL Delay100us
INC R0
DJNZ R2, FCBQ2
LCALL Delay
MOV BZW,#0
SETB TR0
LJMP C0158
FH: SETB TRX_CE ;等待接收完毕 OK
JNB TRX_CE,FH
CLR RACSN
MOV R7,#24H ;读接收数据命令
LCALL SpiReadWrite
CLR A
MOV R7,A
LCALL SpiReadWrite
SETB RACSN
CLR TRX_CE
MOV A,R7
MOV @R0,A
MOV R7,#05H ;延时100微秒
LCALL Delay100us
INC BZW
INC R0
MOV A,BZW
XRL A,#20D
JZ FH0
AJMP FH
FH0: MOVR2,#20D ; OK
MOV R0,#30H
CLR LED0
FH1: MOV A,@R0
MOV R7,A
LCALL PutChar
INC R0
DJNZ R2,FH1
LCALL Delay
MOV BZW,#0
SETB LED0
FH2: ; LCALLDelay
LCALL Delay
LJMP C0158
StartADC: MOV R2,#20
MOV R0,#40H;PUSH ACC
ADC20: CLR RACSN
MOV R7,#0C3h ;START_ADC_CONV(SAV)1100-SSSS=CHSEL=3通道
LCALL SpiReadWrite
SETB RACSN
JNB EOC, $
CLR RACSN
MOV R7,#40h
LCALL SpiReadWrite
MOV R7,#0FFH
LCALL SpiReadWrite
MOV A,R7;07H ;
MOV @R0,A ;
INC R0
DJNZ R2,ADC20
cpl led2
RET
C0185: LCALL SpiReadWrite ;写发送数据地址
MOV R7,#0E7H
LCALL SpiReadWrite
MOV R7,#0E7H
LCALL SpiReadWrite
MOV R7,#0E7H
LCALL SpiReadWrite
MOV R7,#0E7H
SpiReadWrite: ANL EXIF,#0DFH ;Move byte to send to SPI data register
MOV SPI_DATA,R7 ;读写SPI数据
C019E: MOV A,EXIF
JNB 0E0H.5,C019E
MOV R7,SPI_DATA
RET
Delayms: MOV 10H,R7 ;延时子程序
C01A8: MOV R7, 10H
DEC 10H
MOV A,R7
JZ C01BF
CLR A
MOV R5,A
C01B1: MOV A,R5
CLR C
SUBB A,#0AH
JNC C01A8
MOV R7,#0AH
LCALL Delay100us
INC R5
SJMP C01B1
C01BF: RET
Delay100us: MOV 11H,R7
Delay100us1: MOV R7, 11H
DEC 11H
MOV A,R7
JZ C021D
CLR A
MOV R6,A
Delay100us2: MOV A,R6
CLR C
SUBB A,#23H
JNC Delay100us1
INC R6
SJMP Delay100us2
C021D: RET
DELAY: MOV 70H,#0FFH
DELAY1: LCALL DELAY2
DJNZ 70H,DELAY1
RET
DELAY2: MOV 71H,#0FFH
DELAY3: NOP
DJNZ 71H,DELAY3
RET
END
|