基于51单片机和NRF24L01的无线温度监控.docx
- 文档编号:9305139
- 上传时间:2023-02-04
- 格式:DOCX
- 页数:32
- 大小:664.10KB
基于51单片机和NRF24L01的无线温度监控.docx
《基于51单片机和NRF24L01的无线温度监控.docx》由会员分享,可在线阅读,更多相关《基于51单片机和NRF24L01的无线温度监控.docx(32页珍藏版)》请在冰豆网上搜索。
基于51单片机和NRF24L01的无线温度监控
基于51单片机和NRF24L01的无线温度监控
一丶实现功能:
以51单片机为核心实现智能化远程无线温度监控。
利用18B20温度传感器获取温度信号,将需要测量的温度信号自动转化为数字信号,通过无线模块NRF24L01一对一传送将数据传送到接收机,最终单片机将信号转换成LCD可以识别的信息显示输出。
二丶所需原件:
51单片机*2
DS18B20*1(温度测量范围为-55~+125^C)
12M晶振*2
22uf电容*2
5V降压至3.3V降压模块*2
NRF24101无线模块*2
1602液晶显示屏*1
按键*3
蜂鸣器*1
发光二极管*1
排阻10K*9脚*2
四丶NRF12401JI介绍:
1、GFSK调制,硬件集成OSI链路层;
2、具有自动应答和自动再发射功能;
3、片内自动生成报头和CRC校验码;
4、数据传输率为l Mb/s或2Mb/s;
5、SPI速率为0 Mb/s~10 Mb/s;
6、125个频道与其他nRF24系列射频器件相兼容;
7、QFN20引脚4 mm×4 mm封装;
8、供电电压为1.9 V~3.6 V;
封装引脚介绍:
CE:
使能发射或接收;
CSN,SCK,MOSI,MISO:
SPI引脚端,微处理器可通过此引脚配置
nRF24L01:
IRQ:
中断标志位;
VDD:
电源输入端;
VSS:
电源地;
XC2,XC1:
晶体振荡器引脚;
VDD_PA:
为功率放大器供电,输出为1.8 V;
ANT1,ANT2:
天线接口;
IREF:
参考电流输入;
工作模式:
工作原理:
发射数据时,首先将nRF24L01配置为发射模式:
接着把接收节点地址TX_ADDR和有效数据TX_PLD按照时序由SPI口写入nRF24L01缓存区,TX_PLD必须在CSN为低时连续写入,而TX_ADDR在发射时写入一次即可,然后CE置为高电平并保持至少10μs,延迟130μs后发射数据;若自动应答开启,那么nRF24L01在发射数据后立即进入接收模式,接收应答信号(自动应答接收地址应该与接收节点地址TX_ADDR一致)。
如果收到应答,则认为此次通信成功,TX_DS置高,同时TX_PLD从TX FIFO中清除;若未收到应答,则自动重新发射该数据(自动重发已开启),若重发次数(ARC)达到上限,MAX_RT置高,TX FIFO中数据保留以便在次重发;MAX_RT或TX_DS置高时,使IRQ变低,产生中断,通知MCU。
最后发射成功时,若CE为低则nRF24L01进入空闲模式1;若发送堆栈中有数据且CE为高,则进入下一次发射;若发送堆栈中无数据且CE为高,则进入空闲模式2。
接收数据时,首先将nRF24L01配置为接收模式,接着延迟130μs进入接收状态等待数据的到来。
当接收方检测到有效的地址和CRC时,就将数据包存储在
RX FIFO中,同时中断标志位RX_DR置高,IRQ变低,产生中断,通知MCU去取数据。
若此时自动应答开启,接收方则同时进入发射状态回传应答信号。
最后接收成功时,若CE变低,则nRF24L01进入空闲模式1。
在写寄存器之前一定要进入待机模式或掉电模式。
SPI配置:
SPI指令设置
用于SPI接口的常用命令见下表。
当CSN为低时,SPI接口开始等待一条指令,任何一条新指令均由CSN的由高到低的转换开始
寄存器:
读操作
写操作
五丶温度监测:
温度检测模块软件设计DS18B20的测温原理遵循严格的单总线协议,以确保通信数据的准确性,单片机通过时序来写入和读出DS18B20中的数据,包括初始化、读l、读0,写1、写0等操作。
传感器复位后,接收应答信号,跳过读ROM中序列号后,启动温度转换,等待温度转换完毕后,保存数据。
如此反复,完成所有操作。
六丶无线流程:
发射:
首先进行初始化操作,初始化包括设置单片机I/O和SPI相关寄存器两部分其可以和nRF24L01通信。
通过SPI总线配置射频芯片使其进入正确的工作模式。
发射数据时,首先将nRF24L01配置为发射模式。
接着把发送端待发射数据的目标地址TX—ADDR和数据TX
—PLD写入nRF24L01缓冲区,延时后发射数据,其流程图如图4.2所示
接收:
接收数据时,首先将nRF24L01配置为接收模式。
接着延迟进入接收状态等待数据的到来。
当接收方检测到有效地址和CRC时,就将数据包储存在接收堆栈中,同时状态寄存器中的中断标志位RX—DR置高,产生中断使IRQ引脚变为低电平,以便通知MCU去取数据,其流程图如图4.3所示。
七丶软件总体部分:
发送部分:
发送部分的一个循环的总体思路是这样的先初始化DS18B20,从DS18B20读出温度(DS18B20采用默认的12位精度),将得到的温度值的反码转化成十制,取温度数组的高两位(即整数部分)写入发送数据数组,然后初始化nRF24L01,将温度发送,其流程图如图4.5所示
接收部分:
接收部分的总体思路是这样的,首先还是初始化nRF24L01,然后进入大循环判断状态寄存器是否有接收中断。
如果有就从FIFO_buffer读入二进制数据,然后将数据转换成十进制在数码管上显示出来,其流程图如图4.6所示。
八:
电路图:
发射机:
接收机:
九丶程序清单:
接收机:
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
#defineREAD_REG0x00//Definereadcommandtoregister
#defineWRITE_REG0x20//Definewritecommandtoregister
#defineRD_RX_PLOAD0x61//DefineRXpayloadregisteraddress
#defineWR_TX_PLOAD0xA0//DefineTXpayloadregisteraddress
#defineFLUSH_TX0xE1//DefineflushTXregistercommand
#defineFLUSH_RX0xE2//DefineflushRXregistercommand
#defineREUSE_TX_PL0xE3//DefinereuseTXpayloadregistercommand
#defineNOP0xFF//DefineNoOperation,mightbeusedtoreadstatusregister
#defineCONFIG0x00//'Config'registeraddress
#defineEN_AA0x01//'EnableAutoAcknowledgment'registeraddress
#defineEN_RXADDR0x02//'EnabledRXaddresses'registeraddress
#defineSETUP_AW0x03//'Setupaddresswidth'registeraddress
#defineSETUP_RETR0x04//'SetupAuto.Retrans'registeraddress
#defineRF_CH0x05//'RFchannel'registeraddress
#defineRF_SETUP0x06//'RFsetup'registeraddress
#defineSTATUS0x07//'Status'registeraddress
#defineOBSERVE_TX0x08//'ObserveTX'registeraddress
#defineCD0x09//'CarrierDetect'registeraddress
#defineRX_ADDR_P00x0A//'RXaddresspipe0'registeraddress
#defineRX_ADDR_P10x0B//'RXaddresspipe1'registeraddress
#defineRX_ADDR_P20x0C//'RXaddresspipe2'registeraddress
#defineRX_ADDR_P30x0D//'RXaddresspipe3'registeraddress
#defineRX_ADDR_P40x0E//'RXaddresspipe4'registeraddress
#defineRX_ADDR_P50x0F//'RXaddresspipe5'registeraddress
#defineTX_ADDR0x10//'TXaddress'registeraddress
#defineRX_PW_P00x11//'RXpayloadwidth,pipe0'registeraddress
#defineRX_PW_P10x12//'RXpayloadwidth,pipe1'registeraddress
#defineRX_PW_P20x13//'RXpayloadwidth,pipe2'registeraddress
#defineRX_PW_P30x14//'RXpayloadwidth,pipe3'registeraddress
#defineRX_PW_P40x15//'RXpayloadwidth,pipe4'registeraddress
#defineRX_PW_P50x16//'RXpayloadwidth,pipe5'registeraddress
#defineFIFO_STATUS0x17//'FIFOStatusRegister'registeraddress
#defineTX_ADR_WIDTH5
#defineRX_ADR_WIDTH5
#defineTX_PLOAD_WIDTH4
#defineTX_PLOAD_WIDTH4
floatf_temp;
uinttemp;
ucharTX_ADDRESS[5]={0x34,0x43,0x19,0x91,0x09};
ucharbdatasta;
sbitCE=P2^7;
sbitCSN=P2^2;
sbitMOSI=P2^3;
sbitMISO=P2^5;
sbitSCK=P2^6;
sbitIRQ=P2^4;
sbitds=P3^7;
sbitled0=P1^0;
sbitRX_DR=sta^6;
sbitTX_DS=sta^5;
sbitMAX_RT=sta^4;
voidinit_io(void)
{
CE=0;
CSN=1;
SCK=0;
IRQ=1;
}
ucharSPI_RW(ucharbyte)
{
uchari;
for(i=0;i<8;i++)
{
MOSI=(byte&0x80);
byte=(byte<<1);
SCK=1;
byte|=MISO;
SCK=0;
}
return(byte);
}
ucharSPI_RW_reg(ucharreg,ucharvalue)
{
ucharstatus;
CSN=0;
status=SPI_RW(reg);
SPI_RW(value);
CSN=1;
return(status);
}
ucharSPI_read(ucharreg)
{
ucharreg_val;
CSN=0;
SPI_RW(reg);
reg_val=SPI_RW(0);
CSN=1;
return(reg_val);
}
ucharSPI_read_pload(ucharreg,uchar*pBuf,ucharbytes)
{
ucharstatus,i;
CSN=0;
status=SPI_RW(reg);
for(i=0;i pBuf[i]=SPI_RW(0); CSN=1; return(status); } ucharSPI_write_pload(ucharreg,uchar*pBuf,ucharbytes) { ucharstatus,i; CSN=0; status=SPI_RW(reg); for(i=0;i SPI_RW(pBuf[i]); CSN=1; return(status); } voidTX_mode(uchar*tx_buf) { CE=0; SPI_write_pload(WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH); SPI_write_pload(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH); SPI_write_pload(WR_TX_PLOAD,tx_buf,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,0X0e); CE=1;//CE置高,使能发送 } ucharCheck_ACK() { //while(IRQ //CE=0; sta=SPI_read(STATUS); if(TX_DS||MAX_RT) { SPI_RW_reg(WRITE_REG+STATUS,0xff); CSN=0; SPI_RW(FLUSH_TX); CSN=1; return (1); } else return(0); //CE=1; IRQ=1; //if(TX_DS) //return(0x00); //else //return(0xff); } /* ucharCheckACK() { sta=NRFReadReg(READ_REG+STATUS); if(TX_DS||MAX_RT) { NRFWriteReg(WRITE_REG+STATUS,0xff); CSN=0; NRFSPI(FLUSH_TX); CSN=1; return(0); } else return (1); } */ voiddelayus(uintz,uintx) { uinti,j; for(i=z;i>0;i--) for(j=x;j>0;j--); } voiddreset(void) { uinti; //ds=1; //_nop_(); ds=0; delayus(7,15); ds=1; i=4; while(i>0) i--; delayus(1,100); } bittempreadbit(void) { uinti; bitdat; //ds=1;i++; ds=0; _nop_(); ds=1; i++;i++; dat=ds; i=8; while(i>0) i--; return(dat); } uchartempread(void) { uchari,j,dat; dat=0; for(i=0;i<8;i++) { j=tempreadbit(); dat=(j<<7)|(dat>>1); } return(dat); } voidtempwritebyte(uchardat) { uinti; ucharj; bittestb; for(j=0;j<8;j++) { testb=dat&0x01; dat=dat>>1; if(testb) { ds=0; i++;i++; ds=1; i=8; while(i>0) i--; } else { ds=0; //i=8; //while(i>0)i--; delayus(1,5); ds=1; i++;i++; } } } voidtempchange(void) { dreset(); delayus(1,113); tempwritebyte(0xcc); tempwritebyte(0x44); } uintget_temp() { uchara,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; returntemp; } voidmain() { uchartx_buf[4]={0}; init_io(); while (1) { tempchange(); delayus(1,113); get_temp(); tx_buf[0]=(uchar)(temp/100); tx_buf[1]=(uchar)(((temp-500)%100)/10); tx_buf[2]='.'; tx_buf[3]=(uchar)((temp%100)%10); TX_mode(tx_buf); } } 接收机: #include //#include #defineucharunsignedchar #defineuintunsignedint #defineREAD_REG0x00//Definereadcommandtoregister #defineWRITE_REG0x20//Definewritecommandtoregister #defineRD_RX_PLOAD0x61//DefineRXpayloadregisteraddress #defineWR_TX_PLOAD0xA0//DefineTXpayloadregisteraddress #defineFLUSH_TX0xE1//DefineflushTXregistercommand #defineFLUSH_RX0xE2//DefineflushRXregistercommand #defineREUSE_TX_PL0xE3//DefinereuseTXpayloadregistercommand #defineNOP0xFF//DefineNoOperation,mightbeusedtoreadstatusregister //SPI(nRF24L01)registers(addresses) #defineCONFIG0x00//'Config'registeraddress #defineEN_AA0x01//'EnableAutoAcknowledgment'registeraddress #defineEN_RXADDR0x02//'EnabledRXaddresses'registeraddress #defineSETUP_AW0x03//'Setupaddresswidth'registeraddress #defineSETUP_RETR0x04//'SetupAuto.Retrans'registeraddress #defineRF_CH0x05//'RFchannel'registeraddress #defineRF_SETUP0x06//'RFsetup'registeraddress #defineSTATUS0x07//'Status'registeraddress #defineOBSERVE_TX0x08//'ObserveTX'registeraddress #defineCD0x09//'CarrierDetect'registeraddress #defineRX_ADDR_P00x0A//'RXaddresspipe0'registeraddress #defineRX_ADDR_P10x0B//'RXaddresspipe1'registeraddress #defineRX_ADDR_P20x0C//'RXaddresspipe2'registeraddress #defineRX_ADDR_P30x0D//'RXaddresspipe3'registeraddress #defineRX_ADDR_P40x0E//'RXaddresspipe4'registeraddress #defineRX_ADDR_P50x0F//'RXaddresspipe5'registeraddress #defineTX_ADDR0x10//'TXaddress'registeraddress #defineRX_PW_P00x11//'RXpayloadwidth,pipe0'registeraddress #d
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 51 单片机 NRF24L01 无线 温度 监控