找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1549|回复: 1
收起左侧

NRF24L01无线温度监控系统单片机源码

[复制链接]
ID:430168 发表于 2018-11-20 20:35 | 显示全部楼层 |阅读模式
在当今的工农业生产中,需要进行温湿度采集的场合越来越多,准确方便地测量温度变得至关重要。传统的有线测温方式存在着布线复杂,线路容易老化,线路故障难以排查,设备重新布局要重新布线等问题。特别是在有线网络不通畅或由于现场环境因素的限制而不便架设线路的情况下,给温湿度的数据采集带来了很大的麻烦。要想监测到实时的温湿度数据,就必须采用无线传输的方式对数据进行采集、发送、接收并对无线采集来的数据通过上位机进行处理,以控制并监测设备的运行情况,减少不必要的线路设备开支。

  温湿度采集电路设计

  DHT11是一款含有已校准数字信号输出的温湿度复合传感器。该传感器应用专用的数字模块采集技术和温湿度传感技术,具有极高的可靠性与卓越的长期稳定性。图2所示为其温度采集电路。DHT11传感器包括一个电阻式感湿元件和一个NTC 测温元件,可与高性能8位单片机相连接。校准系数以程序的形式储存在OTP 内存中,传感器内部在检测信号的过程中可调用这些校准系数。单线制串行接口可使系统集成变得简易而快捷,而且信号传输距离可达20m 以上。当连接线长度短于20m 时,应使用5kΩ上拉电阻,大于20m 时,应根据情况使用合适的上拉电阻。

0.png

单片机源程序如下:
  1. #include <reg52.h>
  2. #include <intrins.h>

  3. typedef unsigned char uchar;
  4. typedef unsigned char uint;
  5. //****************************************NRF24L01端口定义***************************************
  6. sbit         MISO        =P1^5;
  7. sbit         MOSI        =P1^4;
  8. sbit        SCK            =P1^3;
  9. sbit        CE            =P1^1;
  10. sbit        CSN                =P1^2;
  11. sbit        IRQ                =P3^3;
  12. //************************************按键***************************************************
  13. sbit        KEY1=P3^6;
  14. sbit        KEY2=P3^7;
  15. //************************************数码管位选*********************************************
  16. sbit        led3=P2^4;
  17. sbit        led2=P2^5;
  18. sbit        led1=P2^6;
  19. sbit        led0=P2^7;
  20. //************************************蜂明器***************************************************
  21. sbit         BELL=P2^0;
  22. //***********************************数码管0-9编码*******************************************
  23. uchar seg[10]={0x03,/*0*/
  24.            0x9F,/*1*/
  25.            0x25,/*2*/
  26.            0x0D,/*3*/
  27.            0x99,/*4*/
  28.            0x49,/*5*/
  29.            0x41,/*6*/
  30.            0x1F,/*7*/
  31.            0x01,/*8*/
  32.            0x09,/*9*/};         //0~~9段码
  33. uchar seg1[10]={0x40,0x4F,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};         //0~~9段码
  34. char temp[6];
  35. uchar RxBuf[20]={0};
  36. //*********************************************NRF24L01*************************************
  37. #define TX_ADR_WIDTH    5           // 5 uints TX address width
  38. #define RX_ADR_WIDTH    5           // 5 uints RX address width
  39. #define TX_PLOAD_WIDTH  20          // 20 uints TX payload
  40. #define RX_PLOAD_WIDTH  20          // 20 uints TX payload
  41. uint const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};        //本地地址
  42. uint const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};        //接收地址
  43. //***************************************NRF24L01寄存器指令*******************************************************
  44. #define READ_REG        0x00          // 读寄存器指令
  45. #define WRITE_REG       0x20         // 写寄存器指令
  46. #define RD_RX_PLOAD     0x61          // 读取接收数据指令
  47. #define WR_TX_PLOAD     0xA0          // 写待发数据指令
  48. #define FLUSH_TX        0xE1         // 冲洗发送 FIFO指令
  49. #define FLUSH_RX        0xE2          // 冲洗接收 FIFO指令
  50. #define REUSE_TX_PL     0xE3          // 定义重复装载数据指令
  51. #define NOP             0xFF          // 保留
  52. //*************************************SPI(nRF24L01)寄存器地址****************************************************
  53. #define CONFIG          0x00  // 配置收发状态,CRC校验模式以及收发状态响应方式
  54. #define EN_AA           0x01  // 自动应答功能设置
  55. #define EN_RXADDR       0x02  // 可用信道设置
  56. #define SETUP_AW        0x03  // 收发地址宽度设置
  57. #define SETUP_RETR      0x04  // 自动重发功能设置
  58. #define RF_CH           0x05  // 工作频率设置
  59. #define RF_SETUP        0x06  // 发射速率、功耗功能设置
  60. #define STATUS          0x07  // 状态寄存器
  61. #define OBSERVE_TX      0x08  // 发送监测功能
  62. #define CD              0x09  // 地址检测           
  63. #define RX_ADDR_P0      0x0A  // 频道0接收数据地址
  64. #define RX_ADDR_P1      0x0B  // 频道1接收数据地址
  65. #define RX_ADDR_P2      0x0C  // 频道2接收数据地址
  66. #define RX_ADDR_P3      0x0D  // 频道3接收数据地址
  67. #define RX_ADDR_P4      0x0E  // 频道4接收数据地址
  68. #define RX_ADDR_P5      0x0F  // 频道5接收数据地址
  69. #define TX_ADDR         0x10  // 发送地址寄存器
  70. #define RX_PW_P0        0x11  // 接收频道0接收数据长度
  71. #define RX_PW_P1        0x12  // 接收频道0接收数据长度
  72. #define RX_PW_P2        0x13  // 接收频道0接收数据长度
  73. #define RX_PW_P3        0x14  // 接收频道0接收数据长度
  74. #define RX_PW_P4        0x15  // 接收频道0接收数据长度
  75. #define RX_PW_P5        0x16  // 接收频道0接收数据长度
  76. #define FIFO_STATUS     0x17  // FIFO栈入栈出状态寄存器设置
  77. //**************************************************************************************
  78. void Delay(unsigned int s);
  79. void inerDelay_us(unsigned char n);
  80. void init_NRF24L01(void);
  81. uint SPI_RW(uint uchar);
  82. uchar SPI_Read(uchar reg);
  83. void SetRX_Mode(void);
  84. uint SPI_RW_Reg(uchar reg, uchar value);
  85. uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);
  86. uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);
  87. unsigned char nRF24L01_RxPacket(unsigned char* rx_buf);
  88. void nRF24L01_TxPacket(unsigned char * tx_buf);
  89. //*****************************************长延时*****************************************
  90. void Delay(unsigned int s)
  91. {
  92.         unsigned int i;
  93.         for(i=0; i<s; i++);
  94.         for(i=0; i<s; i++);
  95. }
  96. //******************************************************************************************
  97. uint         bdata sta;   //状态标志
  98. sbit        RX_DR        =sta^6;
  99. sbit        TX_DS        =sta^5;
  100. sbit        MAX_RT        =sta^4;
  101. /******************************************************************************************
  102. /*延时函数
  103. /******************************************************************************************/
  104. void inerDelay_us(unsigned char n)
  105. {
  106.         for(;n>0;n--)
  107.                 _nop_();
  108. }
  109. //****************************************************************************************
  110. /*NRF24L01初始化
  111. //***************************************************************************************/
  112. void init_NRF24L01(void)
  113. {
  114.     inerDelay_us(100);
  115.         CE=0;    // chip enable
  116.         CSN=1;   // Spi disable
  117.         SCK=0;   // Spi clock line init high
  118.         SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    // 写本地地址       
  119.         SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址
  120.         SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);                                                       //  频道0自动        ACK应答允许       
  121.         SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  //  允许接收地址只有频道0,如果需要多频道,可以参考Page21  
  122.         SPI_RW_Reg(WRITE_REG + RF_CH, 0);        //   设置信道工作为2.4GHZ,收发必须一致
  123.         SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32纸?
  124.         SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);                   //设置发射速率为1MHZ,发射功率为最大值0dB
  125. }
  126. /****************************************************************************************************
  127. /*函数:uint SPI_RW(uint uchar)
  128. /*功能:NRF24L01的SPI写时序
  129. /*详细请参考Page19
  130. /****************************************************************************************************/
  131. uint SPI_RW(uint uchar)
  132. {
  133.         uint bit_ctr;
  134.            for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
  135.            {
  136.                 MOSI = (uchar & 0x80);         // output 'uchar', MSB to MOSI
  137.                 uchar = (uchar << 1);           // shift next bit into MSB..
  138.                 SCK = 1;                      // Set SCK high..
  139.                 uchar |= MISO;                         // capture current MISO bit
  140.                 SCK = 0;                              // ..then set SCK low again
  141.            }
  142.     return(uchar);                             // return read uchar
  143. }
  144. /****************************************************************************************************
  145. /*函数:uchar SPI_Read(uchar reg)
  146. /*功能:NRF24L01的SPI时序
  147. /*详细请参考Page19
  148. /****************************************************************************************************/
  149. uchar SPI_Read(uchar reg)
  150. {
  151.         uchar reg_val;
  152.        
  153.         CSN = 0;                // CSN low, initialize SPI communication...
  154.         SPI_RW(reg);            // Select register to read from..
  155.         reg_val = SPI_RW(0);    // ..then read registervalue
  156.         CSN = 1;                // CSN high, terminate SPI communication
  157.        
  158.         return(reg_val);        // return register value
  159. }
  160. /****************************************************************************************************/
  161. /*功能:NRF24L01读写寄存器函数
  162. /****************************************************************************************************/
  163. uint SPI_RW_Reg(uchar reg, uchar value)
  164. {
  165.         uint status;
  166.        
  167.         CSN = 0;                   // CSN low, init SPI transaction
  168.         status = SPI_RW(reg);      // select register
  169.         SPI_RW(value);             // ..and write value to it..
  170.         CSN = 1;                   // CSN high again
  171.        
  172.         return(status);            // return nRF24L01 status uchar
  173. }
  174. /****************************************************************************************************/
  175. /*函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
  176. /*功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数
  177. /****************************************************************************************************/
  178. uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
  179. {
  180.         uint status,uchar_ctr;
  181.        
  182.         CSN = 0;                                    // Set CSN low, init SPI tranaction
  183.         status = SPI_RW(reg);                       // Select register to write to and read status uchar
  184.        
  185.         for(uchar_ctr=0;uchar_ctr<uchars;uchar_ctr++)
  186.                 pBuf[uchar_ctr] = SPI_RW(0);    //
  187.        
  188.         CSN = 1;                           
  189.        
  190.         return(status);                    // return nRF24L01 status uchar
  191. }
  192. /*********************************************************************************************************
  193. /*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
  194. /*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数
  195. /*********************************************************************************************************/
  196. uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
  197. {
  198.         uint status,uchar_ctr;
  199.        
  200.         CSN = 0;            //SPI使能      
  201.         status = SPI_RW(reg);   
  202.         for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++) //
  203.                 SPI_RW(*pBuf++);
  204.         CSN = 1;           //关闭SPI
  205.         return(status);    //
  206. }
  207. /****************************************************************************************************/
  208. /*函数:void SetRX_Mode(void)
  209. /*功能:数据接收配置
  210. /****************************************************************************************************/
  211. void SetRX_Mode(void)
  212. {
  213.         CE=0;
  214.         SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);                   // IRQ收发完成中断响应,16位CRC        ,主接收
  215.         CE = 1;
  216.         inerDelay_us(130);
  217. }
  218. /******************************************************************************************************/
  219. /*函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
  220. /*功能:数据读取后放如rx_buf接收缓冲区中
  221. /******************************************************************************************************/
  222. unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
  223. {
  224.     unsigned char revale=0;
  225.         sta=SPI_Read(STATUS);        // 读取状态寄存其来判断数据接收状况
  226.         if(RX_DR)                                // 判断是否接收到数据
  227.         {
  228.             CE = 0;                        
  229.         SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer
  230.                 revale =1;                        //读取数据完成标志
  231.         }
  232.         SPI_RW_Reg(WRITE_REG+STATUS,sta);   //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来其清除中断标志
  233.         return revale;
  234. }
  235. /***********************************************************************************************************
  236. /*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)
  237. /*功能:发送 tx_buf中数据
  238. /**********************************************************************************************************/
  239. void nRF24L01_TxPacket(unsigned char * tx_buf)
  240. {
  241.         CE=0;                        //StandBy I模式       
  242.         SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址
  243.         SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH);                          // 装载数据       
  244.         SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);                    // IRQ收发完成中断响应,16位CRC,主发送
  245.         CE=1;                 //置高CE,激发数据发送
  246.         inerDelay_us(10);
  247. }
  248. //***********************************************串口初始化***********************************************
  249. void StartUART( void )       
  250. {                                                 
  251.      SCON = 0x50;
  252.      TMOD = 0x20;
  253.      TH1 = 0xFA;
  254.      TL1 = 0xFA;                        //波特率4800
  255.      PCON = 0x00;
  256.      TR1 = 1;
  257. }
  258. //***********************************************通过串口向PC发送***********************************************
  259. void R_S_Byte(uchar R_Byte)
  260. {       
  261.          SBUF = R_Byte;  
  262.      while( TI == 0 );                                //查询法
  263.            TI = 0;   
  264. }
  265. //***********************************************数码动态扫描显示***********************************************
  266. void disdignit()
  267. {
  268.         P0=0xC6;                          //C
  269.         led0=0;
  270.         Delay(50);
  271.         led0=1;
  272.         P0=seg[temp[1]];          //小数位
  273.         led1=0;
  274.         Delay(50);
  275.         led1=1;
  276.         P0=seg1[temp[5]];    //十位
  277.         led2=0;
  278.         Delay(50);
  279.         led2=1;
  280.         P0=seg[temp[4]];           //个位
  281.         led3=0;
  282.         Delay(50);
  283.         led3=1;
  284. }
  285. //************************************主函数************************************************************
  286. void main(void)
  287. {
  288.         uchar i=0;       
  289.     init_NRF24L01() ;                        //NRF24L01初始化
  290.         StartUART();
  291.         Delay(6000);
  292.         BELL=1;
  293.         while(1)
  294.         {
  295. //***********************************************************************************************
  296.                 SetRX_Mode();
  297.                    if(nRF24L01_RxPacket(RxBuf))
  298.                 {
  299.                         temp[0]=RxBuf[3];                                                      //符号位
  300.                         temp[2]=((RxBuf[2]<<4)|RxBuf[1]);                        //整数位
  301.                         temp[1]=RxBuf[0];                                                        //小数位
  302.                     temp[4]=RxBuf[2];                                                        //十位
  303.                      temp[5]=RxBuf[1];                                                        //个位
  304.                         disdignit();                //数码管显示温度
  305.                         R_S_Byte('t');     //串口显示温度
  306.                         disdignit();                //数码管显示温度
  307.                         disdignit();                //数码管显示温度
  308.                         R_S_Byte(0x30+temp[4]);     //串口显示温度
  309.                         R_S_Byte(0x30+temp[5]);     //串口显示温度
  310.                         R_S_Byte('.');     //串口显示温度
  311.                         R_S_Byte(0x30+temp[1]);     //串口显示温度
  312.                         disdignit();                //数码管显示温度
  313.                         disdignit();                //数码管显示温度
  314.                         disdignit();                //数码管显示温度
  315.                 /*        for(i=0;i<3;i++)
  316.                         {
  317.                         R_S_Byte(temp[2-i]);     //串口显示温度
  318.                         Delay(60);
  319.                         } */
  320.                 }
  321.                         disdignit();                //数码管显示温度
  322.                        
  323.                 if(temp[2]>=0x30)                        //大于30度时报警,0x30转换成10进制为48
  324.                 {
  325.                         BELL=0;                           //打开蜂明器
  326.                 //        Delay(1);
  327.                 }
  328.                 else
  329.                 {
  330.                         BELL=1;                  //关闭蜂明器
  331.         }       

  332.                
  333.                
  334.                 }
  335. }
复制代码

所有资料51hei提供下载:
21、NRF24L01无线温度监控系统.zip (2.49 MB, 下载次数: 57)


回复

使用道具 举报

ID:428614 发表于 2019-4-22 14:48 | 显示全部楼层
你好答主,请问能请教个问题吗?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表