《基于51单片机和NRF24L01的无线温度监控.doc》由会员分享,可在线阅读,更多相关《基于51单片机和NRF24L01的无线温度监控.doc(30页珍藏版)》请在三一办公上搜索。
1、基于51单片机和NRF24L01的无线温度监控一丶实现功能:以51单片机为核心实现智能化远程无线温度监控。利用18B20温度传感器获取温度信号,将需要测量的温度信号自动转化为数字信号,通过无线模块NRF24L01一对一传送将数据传送到接收机,最终单片机将信号转换成LCD可以识别的信息显示输出。二丶所需原件:51单片机*2DS18B20*1 (温度测量范围为-55+125C)12M晶振*222uf电容*25V降压至3.3V降压模块*2NRF24101无线模块*21602液晶显示屏*1按键*3蜂鸣器*1发光二极管*1排阻10K*9脚*2四丶NRF12401JI介绍:1、GFSK调制,硬件集成OSI
2、链路层;2、具有自动应答和自动再发射功能;3、片内自动生成报头和CRC校验码;4、数据传输率为lMb/s或2Mb/s;5、SPI速率为0Mb/s10Mb/s;6、125个频道与其他nRF24系列射频器件相兼容;7、 QFN20引脚4mm4mm封装;8、 供电电压为1.9V3.6V;封装引脚介绍:CE:使能发射或接收;CSN,SCK,MOSI,MISO:SPI引脚端,微处理器可通过此引脚配置nRF24L01:IRQ:中断标志位;VDD:电源输入端;VSS:电源地;XC2,XC1:晶体振荡器引脚; VDD_PA:为功率放大器供电,输出为1.8V;ANT1,ANT2:天线接口;IREF:参考电流输入
3、;工作模式:工作原理:发射数据时,首先将nRF24L01配置为发射模式:接着把接收节点地址TX_ADDR和有效数据TX_PLD按照时序由SPI口写入nRF24L01缓存区,TX_PLD必须在CSN为低时连续写入,而TX_ADDR在发射时写入一次即可,然后CE置为高电平并保持至少10s,延迟130s后发射数据;若自动应答开启,那么nRF24L01在发射数据后立即进入接收模式,接收应答信号(自动应答接收地址应该与接收节点地址TX_ADDR一致)。如果收到应答,则认为此次通信成功,TX_DS置高,同时TX_PLD从TXFIFO中清除;若未收到应答,则自动重新发射该数据(自动重发已开启),若重发次数(
4、ARC)达到上限,MAX_RT置高,TXFIFO中数据保留以便在次重发;MAX_RT或TX_DS置高时,使IRQ变低,产生中断,通知MCU。最后发射成功时,若CE为低则nRF24L01进入空闲模式1;若发送堆栈中有数据且CE为高,则进入下一次发射;若发送堆栈中无数据且CE为高,则进入空闲模式2。接收数据时,首先将nRF24L01配置为接收模式,接着延迟130s进入接收状态等待数据的到来。当接收方检测到有效的地址和CRC时,就将数据包存储在RXFIFO中,同时中断标志位RX_DR置高,IRQ变低,产生中断,通知MCU去取数据。若此时自动应答开启,接收方则同时进入发射状态回传应答信号。最后接收成功
5、时,若CE变低,则nRF24L01进入空闲模式1。在写寄存器之前一定要进入待机模式或掉电模式。SPI配置:SPI 指令设置用于SPI 接口的常用命令见下表。当CSN 为低时,SPI 接口开始等待一条指令,任何一条新指令均由CSN 的由高到低的转换开始寄存器:读操作写操作五丶温度监测:温度检测模块软件设计DS18B20的测温原理遵循严格的单总线协议,以确保通信数据的准确性,单片机通过时序来写入和读出DS18B20中的数据,包括初始化、读l、读0,写1、写0等操作。传感器复位后,接收应答信号,跳过读ROM中序列号后,启动温度转换,等待温度转换完毕后,保存数据。如此反复,完成所有操作。六丶无线流程:
6、发射:首先进行初始化操作,初始化包括设置单片机IO和SPI相关寄存器两部分其可以和nRF24L01通信。通过SPI总线配置射频芯片使其进入正确的工作模式。发射数据时,首先将nRF24L01配置为发射模式。接着把发送端待发射数据的目标地址TX ADDR和数据TXPLD写入nRF24L01缓冲区,延时后发射数据,其流程图如图4.2所示接收:接 收 数 据 时 ,首先将nRF24L01配置为接收模式。接着延迟进入接收状态等待数据的到来。当接收方检测到有效地址和CRC时,就将数据包储存在接收堆栈中,同时状态寄存器中的中断标志位RXDR置高,产生中断使IRQ引脚变为低电平,以便通知MCU去取数据,其流程
7、图如图4.3所示。七丶软件总体部分:发送部分:发送部分的一个循环的总体思路是这样的先初始化DS18B20,从DS18B20读出温度(DS18B20采用默认的12位精度),将得到的温度值的反码转化成十制,取温度数组的高两位(即整数部分)写入发送数据数组,然后初始化nRF24L01,将温度发送,其流程图如图4.5所示接收部分:接收部分的总体思路是这样的,首先还是初始化nRF24L01,然后进入大循环判断状态寄存器是否有接收中断。如果有就从FIFO_buffer读入二进制数据,然后将数据转换成十进制在数码管上显示出来,其流程图如图4.6所示。八:电路图:发射机: 接收机:九丶程序清单:接收机:#in
8、clude #include #define uchar unsigned char#define uint unsigned int #define READ_REG 0x00 / Define read command to register #define WRITE_REG 0x20 / Define write command to register #define RD_RX_PLOAD 0x61 / Define RX payload register address #define WR_TX_PLOAD 0xA0 / Define TX payload register ad
9、dress #define FLUSH_TX 0xE1 / Define flush TX register command #define FLUSH_RX 0xE2 / Define flush RX register command #define REUSE_TX_PL 0xE3 / Define reuse TX payload register command #define NOP 0xFF / Define No Operation, might be used to read status register #define CONFIG 0x00 / Config regis
10、ter address #define EN_AA 0x01 / Enable Auto Acknowledgment register address #define EN_RXADDR 0x02 / Enabled RX addresses register address #define SETUP_AW 0x03 / Setup address width register address #define SETUP_RETR 0x04 / Setup Auto. Retrans register address #define RF_CH 0x05 / RF channel regi
11、ster address #define RF_SETUP 0x06 / RF setup register address #define STATUS 0x07 / Status register address #define OBSERVE_TX 0x08 / Observe TX register address #define CD 0x09 / Carrier Detect register address #define RX_ADDR_P0 0x0A / RX address pipe0 register address #define RX_ADDR_P1 0x0B / R
12、X address pipe1 register address #define RX_ADDR_P2 0x0C / RX address pipe2 register address #define RX_ADDR_P3 0x0D / RX address pipe3 register address #define RX_ADDR_P4 0x0E / RX address pipe4 register address #define RX_ADDR_P5 0x0F / RX address pipe5 register address #define TX_ADDR 0x10 / TX a
13、ddress register address #define RX_PW_P0 0x11 / RX payload width, pipe0 register address #define RX_PW_P1 0x12 / RX payload width, pipe1 register address #define RX_PW_P2 0x13 / RX payload width, pipe2 register address #define RX_PW_P3 0x14/ RX payload width, pipe3 register address #define RX_PW_P4
14、0x15 / RX payload width, pipe4 register address #define RX_PW_P5 0x16 / RX payload width, pipe5 register address #define FIFO_STATUS 0x17 / FIFO Status Register register address#define TX_ADR_WIDTH 5 #define RX_ADR_WIDTH 5 #define TX_PLOAD_WIDTH 4#define TX_PLOAD_WIDTH 4 float f_temp; uint temp; uch
15、ar TX_ADDRESS5=0x34,0x43,0x19,0x91,0x09;uchar bdata sta; sbit CE=P27; sbit CSN=P22; sbit MOSI=P23; sbit MISO=P25; sbit SCK=P26; sbit IRQ=P24; sbit ds=P37; sbit led0=P10; sbit RX_DR= sta6; sbit TX_DS= sta5; sbit MAX_RT= sta4; void init_io(void) CE = 0; CSN = 1; SCK = 0; IRQ = 1; uchar SPI_RW(uchar by
16、te) uchar i; for(i=0;i8;i+) MOSI=(byte&0x80); byte=(byte1); SCK=1; byte|=MISO; SCK=0; return(byte); uchar SPI_RW_reg(uchar reg,uchar value) uchar status; CSN=0; status=SPI_RW(reg); SPI_RW(value);CSN=1; return(status); uchar SPI_read(uchar reg) uchar reg_val; CSN=0; SPI_RW(reg); reg_val=SPI_RW(0); CS
17、N=1; return(reg_val); uchar SPI_read_pload(uchar reg,uchar *pBuf,uchar bytes) uchar status,i; CSN=0; status=SPI_RW(reg); for(i=0;ibytes;i+) pBufi=SPI_RW(0); CSN=1; return(status); uchar SPI_write_pload(uchar reg,uchar *pBuf,uchar bytes) uchar status,i; CSN=0; status=SPI_RW(reg); for(i=0;i0;i-) for(j
18、=x;j0;j-); void dreset(void) uint i; / ds=1; / _nop_();ds=0; delayus(7,15); ds=1; i=4; while(i0) i-; delayus(1,100); bit tempreadbit(void) uint i; bit dat; /ds=1;i+; ds=0; _nop_(); ds=1; i+;i+; dat=ds; i=8; while(i0)i-; return(dat); uchar tempread(void) uchar i,j,dat; dat=0; for(i=0;i8;i+) j=temprea
19、dbit(); dat=(j1); return(dat); void tempwritebyte(uchar dat) uint i; uchar j; bit testb; for(j=0;j1; if(testb) ds=0; i+;i+; ds=1; i=8; while(i0)i-; else ds=0; / i=8; / while(i0)i-; delayus(1,5); ds=1; i+;i+; void tempchange(void) dreset(); delayus(1,113); tempwritebyte(0xcc); tempwritebyte(0x44); ui
20、nt get_temp() uchar a,b;dreset(); delayus(1,113); tempwritebyte(0xcc); tempwritebyte(0xbe); a=tempread(); b=tempread(); temp=b; temp=8; temp=temp|a; f_temp=temp*0.0625; temp=f_temp*10+0.5; /f_temp=f_temp+0.05; return temp; void main() uchar tx_buf4=0; init_io(); while(1) tempchange(); delayus(1,113)
21、; get_temp(); tx_buf0=(uchar)(temp/100); tx_buf1=(uchar)(temp-500)%100)/10); tx_buf2=.; tx_buf3=(uchar)(temp%100)%10); TX_mode(tx_buf); 接收机:#include /#include #define uchar unsigned char #define uint unsigned int #define READ_REG 0x00 / Define read command to register #define WRITE_REG 0x20 / Define
22、 write command to register #define RD_RX_PLOAD 0x61 / Define RX payload register address #define WR_TX_PLOAD 0xA0 / Define TX payload register address #define FLUSH_TX 0xE1 / Define flush TX register command #define FLUSH_RX 0xE2 / Define flush RX register command #define REUSE_TX_PL 0xE3 / Define r
23、euse TX payload register command #define NOP 0xFF / Define No Operation, might be used to read status register / SPI(nRF24L01) registers(addresses) #define CONFIG 0x00 / Config register address #define EN_AA 0x01 / Enable Auto Acknowledgment register address #define EN_RXADDR 0x02 / Enabled RX addre
24、sses register address #define SETUP_AW 0x03 / Setup address width register address #define SETUP_RETR 0x04 / Setup Auto. Retrans register address #define RF_CH 0x05 / RF channel register address #define RF_SETUP 0x06 / RF setup register address #define STATUS 0x07 / Status register address #define O
25、BSERVE_TX 0x08 / Observe TX register address #define CD 0x09 / Carrier Detect register address #define RX_ADDR_P0 0x0A / RX address pipe0 register address #define RX_ADDR_P1 0x0B / RX address pipe1 register address #define RX_ADDR_P2 0x0C / RX address pipe2 register address #define RX_ADDR_P3 0x0D /
26、 RX address pipe3 register address #define RX_ADDR_P4 0x0E / RX address pipe4 register address #define RX_ADDR_P5 0x0F / RX address pipe5 register address #define TX_ADDR 0x10 / TX address register address #define RX_PW_P0 0x11 / RX payload width, pipe0 register address #define RX_PW_P1 0x12 / RX pa
27、yload width, pipe1 register address #define RX_PW_P2 0x13 / RX payload width, pipe2 register address #define RX_PW_P3 0x14 / RX payload width, pipe3 register address #define RX_PW_P4 0x15 / RX payload width, pipe4 register address #define RX_PW_P5 0x16 / RX payload width, pipe5 register address #def
28、ine FIFO_STATUS 0x17 / FIFO Status Register register address#define TX_ADR_WIDTH 5 #define RX_ADR_WIDTH 5 #define TX_PLOAD_WIDTH 4 #define RX_PLOAD_WIDTH 4 uchar idata rxbuf12=0; /uchar idata aa20=0; uchar RX_ADDRES5=0x34,0x43,0x19,0x91,0x09; uchar code table=0123456789; uchar bdata sta; sbit RX_DR=
29、 sta6; sbit TX_DS= sta5; sbit MAX_RT= sta4;sbit lcd_rs=P10; sbit lcd_rw=P11; sbit lcd_en=P12;sbit CE =P27; sbit CSN =P22; sbit MOSI=P23; sbit MISO=P25; sbit SCK =P26; sbit IRQ =P24;sbit K1=P34; sbit K2=P36; sbit K3=P35; sbit BJ=P13; sbit BEEF=P14;uchar MAX=30; uchar MIN=20;uchar a; bit flag=0; uchar
30、 slnum=0; void delayms(uint x) uint i,j; for(i=x;i0;i-) for(j=113;j0;j-); void init_io(void) CE = 0; CSN = 1; SCK = 0; IRQ = 1; uchar SPI_RW(uchar byte) uchar i; for(i=0;i8;i+) MOSI=(byte&0x80); byte=(byte1); SCK=1; byte|=MISO; SCK=0; return(byte); uchar SPI_RW_reg(uchar reg,uchar value) uchar statu
31、s; CSN=0; status=SPI_RW(reg); SPI_RW(value); CSN=1; return(status); uchar SPI_read(uchar reg) uchar reg_val; CSN=0; SPI_RW(reg); reg_val=SPI_RW(0); CSN=1; return(reg_val); uchar SPI_read_pload(uchar reg,uchar *pBuf,uchar bytes) uchar status,i; CSN=0; status=SPI_RW(reg); for(i=0;ibytes;i+) pBufi=SPI_
32、RW(0); CSN=1; return(status); uchar SPI_write_pload(uchar reg,uchar *pBuf,uchar bytes) uchar status,i; CSN=0; status=SPI_RW(reg); for(i=0;ibytes;i+) SPI_RW(pBufi); CSN=1; return(status); void RX_mode() CE=0; SPI_write_pload(WRITE_REG+RX_ADDR_P0,RX_ADDRES,TX_ADR_WIDTH); SPI_RW_reg(WRITE_REG+RX_PW_P0,
33、TX_PLOAD_WIDTH); SPI_RW_reg(WRITE_REG+EN_AA,0X01); SPI_RW_reg(WRITE_REG+EN_RXADDR,0X01); SPI_RW_reg(WRITE_REG+SETUP_RETR,0X1F); SPI_RW_reg(WRITE_REG+RF_CH,40); SPI_RW_reg(WRITE_REG+RF_SETUP,0X0F); SPI_RW_reg(WRITE_REG+CONFIG,0X0F); CE=1; uchar RxPacket(uchar *rx_buf) uchar flag=0; sta=SPI_read(STATU
34、S); if(RX_DR) CE=0; SPI_read_pload(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH); flag=1; SPI_RW_reg(WRITE_REG+STATUS,0xff); CSN=0; SPI_RW(FLUSH_RX); CSN=1; CE=1; return(flag); void write_com(uchar com) lcd_rs=0; lcd_rw=0; P0=com; lcd_en=1; delayms(1); lcd_en=0; void write_data(uchar date) lcd_rs=1; lcd_rw=0;
35、P0=date ; lcd_en=1; delayms(1); lcd_en=0; void lcd_init() lcd_en=0; write_com(0x38); write_com(0x0c); write_com(0x06); write_com(0x01); void write_str(uchar x,uchar y,uchar *s) switch(y) case 0: write_com(0x08+x); break; case 1: write_com(0x08+0x40+x); break; while(*s) write_data(*s); s+; void write
36、_maxmin(uchar add,uchar date) uchar shi,ge; shi=date/10; ge=date%10;write_com(0x80+add); write_data(0x30+shi); write_data(0x30+ge); void keyscan() uchar slnum; if(K1=0) delayms(5); if(K1=0) while(!K1); MAX+; if(MAX=99) MAX=0 ; write_maxmin(4,MAX); write_com(0x80+4);delayms(100); if(K3=0) while(!K3);
37、 MIN-; if(MIN=0) MIN=90; write_maxmin(14,MIN); write_com(0x80+14); delayms(100); void main() uchar rx_buf4=0,0,temp; lcd_init(); init_io(); write_com(0x80+0);write_data(M); write_com(0x80+1);write_data(A); write_com(0x80+2);write_data(X); write_com(0x80+3);write_data(:);write_com(0x80+4);write_data(
38、3);write_com(0x80+5);write_data(0);write_com(0x80+10);write_data(M); write_com(0x80+11);write_data(I); write_com(0x80+12);write_data(N); write_com(0x80+13);write_data(:);write_com(0x80+14);write_data(2);write_com(0x80+15);write_data(0); write_com(0xc0+0);write_data(N); write_com(0xc0+1);write_data(O); write_com(0xc0+2);write_data(W); write_com(0xc0+3);write_data(:);write_com(0xc0+10);write_data();write_com(0xc0+11);write_data(C); while(1)