找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2126|回复: 2
收起左侧

分享一个nrf24l01单向传输温度和土壤湿度的单片机程序源码

[复制链接]
ID:413530 发表于 2019-5-21 11:16 | 显示全部楼层 |阅读模式
V(VQ]NF@7)E}O{GD098WR`P.png

单片机源程序如下:
  1. // Define SPI pins
  2. #include <reg51.h>
  3. #include <string.h>

  4. #define uchar unsigned char
  5. #define uint  unsigned int
  6. #define ulong unsigned long
  7. /****************************/
  8. #define     LCDIO      P0  //1602数据口
  9. /*
  10. sbit rs=P2^6;  //1602数据命令选择引脚
  11. sbit rd=P2^5;        //读写选择
  12. sbit lcden=P2^7;        //1602选通引脚
  13. */
  14. sbit rs=P2^5;  //1602数据命令选择引脚
  15. sbit rd=P2^6;        //读写选择
  16. sbit lcden=P2^7;        //1602选通引脚
  17. sbit key=P2^2;
  18. sbit beep=P2^4;
  19. uchar xiao,ge,shi,bai;
  20. float f_temp; //浮点型温度值   
  21. long int tvalue;//温度值
  22. uchar tflag;
  23. uchar code table[]=        {"T:        TH:30 "};    //每行显示16个字符
  24. uchar code table1[]=        {"S:              "};
  25. uchar data disdata[5];
  26. uchar a,b;
  27. /****************************/
  28. /***************************************************/
  29. #define TX_ADR_WIDTH   5  // 5???????/????
  30. #define TX_PLOAD_WIDTH 5  // ??????????

  31. sbit LED = P2^3;

  32. uchar code TX_ADDRESS[TX_ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x01};  // ??????????
  33. uchar RX_BUF[TX_PLOAD_WIDTH];
  34. uchar TX_BUF[TX_PLOAD_WIDTH];
  35. uchar flag;
  36. uchar DATA = 0x01;
  37. uchar bdata sta;
  38. sbit  RX_DR     = sta^6;
  39. sbit  TX_DS     = sta^5;
  40. sbit  MAX_RT = sta^4;

  41. sbit CE =  P1^5;
  42. sbit CSN=  P1^0;
  43. sbit SCK=  P1^4;
  44. sbit MOSI= P1^1;
  45. sbit MISO= P1^3;
  46. sbit IRQ = P1^2;

  47. /*sbit CE =  P3^3;
  48. sbit CSN=  P2^4;
  49. sbit SCK=  P2^0;
  50. sbit MOSI= P2^2;
  51. sbit MISO= P2^1;
  52. sbit IRQ = P2^3;*/

  53. // SPI(nRF24L01) commands
  54. #define READ_REG    0x00  // Define read command to register
  55. #define WRITE_REG   0x20  // Define write command to register
  56. #define RD_RX_PLOAD 0x61  // Define RX payload register address
  57. #define WR_TX_PLOAD 0xA0  // Define TX payload register address
  58. #define FLUSH_TX    0xE1  // Define flush TX register command
  59. #define FLUSH_RX    0xE2  // Define flush RX register command
  60. #define REUSE_TX_PL 0xE3  // Define reuse TX payload register command
  61. #define NOP         0xFF  // Define No Operation, might be used to read status register

  62. // SPI(nRF24L01) registers(addresses)
  63. #define CONFIG      0x00  // 'Config' register address
  64. #define EN_AA       0x01  // 'Enable Auto Acknowledgment' register address
  65. #define EN_RXADDR   0x02  // 'Enabled RX addresses' register address
  66. #define SETUP_AW    0x03  // 'Setup address width' register address
  67. #define SETUP_RETR  0x04  // 'Setup Auto. Retrans' register address
  68. #define RF_CH       0x05  // 'RF channel' register address
  69. #define RF_SETUP    0x06  // 'RF setup' register address
  70. #define STATUS      0x07  // 'Status' register address
  71. #define OBSERVE_TX  0x08  // 'Observe TX' register address
  72. #define CD          0x09  // 'Carrier Detect' register address
  73. #define RX_ADDR_P0  0x0A  // 'RX address pipe0' register address
  74. #define RX_ADDR_P1  0x0B  // 'RX address pipe1' register address
  75. #define RX_ADDR_P2  0x0C  // 'RX address pipe2' register address
  76. #define RX_ADDR_P3  0x0D  // 'RX address pipe3' register address
  77. #define RX_ADDR_P4  0x0E  // 'RX address pipe4' register address
  78. #define RX_ADDR_P5  0x0F  // 'RX address pipe5' register address
  79. #define TX_ADDR     0x10  // 'TX address' register address
  80. #define RX_PW_P0    0x11  // 'RX payload width, pipe0' register address
  81. #define RX_PW_P1    0x12  // 'RX payload width, pipe1' register address
  82. #define RX_PW_P2    0x13  // 'RX payload width, pipe2' register address
  83. #define RX_PW_P3    0x14  // 'RX payload width, pipe3' register address
  84. #define RX_PW_P4    0x15  // 'RX payload width, pipe4' register address
  85. #define RX_PW_P5    0x16  // 'RX payload width, pipe5' register address
  86. #define FIFO_STATUS 0x17  // 'FIFO Status Register' register address

  87. //--??SPI???? IO--//
  88. /*sbit MOSIO = P3^4;
  89. sbit R_CLK = P3^5;
  90. sbit S_CLK = P3^6;*/

  91. void blink(char i);
  92. //--??????--//

  93. /**************************************************
  94. ??: init_io()

  95. ??:
  96.     ???IO
  97. /**************************************************/
  98. void init_io(void)
  99. {
  100.     CE  = 0;        // ??
  101.     CSN = 1;        // SPI??
  102.     SCK = 0;        // SPI????
  103.     IRQ = 1;        // ????
  104.     LED = 1;        // ?????
  105. }
  106. /**************************************************/

  107. /**************************************************
  108. ??:delay_ms()

  109. ??:
  110.     ??x??
  111. /**************************************************/
  112. void delay_ms(uchar x)
  113. {
  114.     uchar i, j;
  115.     i = 0;
  116.     for(i=0; i<x; i++)
  117.     {
  118.        j = 250;
  119.        while(--j);
  120.        j = 250;
  121.        while(--j);
  122.     }
  123. }
  124. /**************************************************/

  125. /**************************************************
  126. ??:SPI_RW()

  127. ??:
  128.     ??SPI??,???????nRF24L01,???nRF24L01
  129.     ?????
  130. /**************************************************/
  131. uchar SPI_RW(uchar byte)
  132. {
  133.     uchar i;
  134.        for(i=0; i<8; i++)          // ??8?
  135.        {
  136.            MOSI = (byte & 0x80);   // byte??????MOSI
  137.            byte <<= 1;             // ?????????
  138.            SCK = 1;                // ??SCK,nRF24L01?MOSI??1???,???MISO??1???
  139.            byte |= MISO;           // ?MISO?byte???
  140.            SCK = 0;                // SCK??
  141.        }
  142.     return(byte);               // ????????
  143. }
  144. /**************************************************/

  145. /**************************************************
  146. ??:SPI_RW_Reg()

  147. ??:
  148.     ???value?reg???
  149. /**************************************************/
  150. uchar SPI_RW_Reg(uchar reg, uchar value)
  151. {
  152.     uchar status;
  153.       CSN = 0;                   // CSN??,??????
  154.       status = SPI_RW(reg);      // ?????,???????
  155.       SPI_RW(value);             // ??????????
  156.       CSN = 1;                   // CSN??,??????
  157.       return(status);            // ???????
  158. }
  159. /**************************************************/

  160. /**************************************************
  161. ??:SPI_Read()

  162. ??:
  163.     ?reg???????
  164. /**************************************************/
  165. uchar SPI_Read(uchar reg)
  166. {

  167.     uchar reg_val;
  168.       //blink(4);
  169.     CSN = 0;                    // CSN??,??????
  170.       SPI_RW(reg);                // ?????
  171.       reg_val = SPI_RW(0);        // ??????????
  172.     //delay_ms(200);
  173.       CSN = 1;                    // CSN??,??????
  174.       return(reg_val);            // ???????
  175. }
  176. /**************************************************/

  177. /**************************************************
  178. ??:SPI_Read_Buf()

  179. ??:
  180.     ?reg?????bytes???,??????????
  181.     ?????/????
  182. /**************************************************/
  183. uchar SPI_Read_Buf(uchar reg, uchar * pBuf, uchar bytes)
  184. {
  185.     uchar status, i;
  186.       CSN = 0;                    // CSN??,??????
  187.       status = SPI_RW(reg);       // ?????,???????
  188.       for(i=0; i<bytes; i++)
  189.         pBuf[i] = SPI_RW(0);    // ?????nRF24L01??
  190.       CSN = 1;                    // CSN??,??????
  191.       return(status);             // ???????
  192. }
  193. /**************************************************/

  194. /**************************************************
  195. ??:SPI_Write_Buf()

  196. ??:
  197.     ?pBuf?????????nRF24L01,???????
  198.     ????????/????
  199. /**************************************************/
  200. uchar SPI_Write_Buf(uchar reg, uchar * pBuf, uchar bytes)
  201. {
  202.     uchar status, i;
  203.       CSN = 0;                    // CSN??,??????
  204.       status = SPI_RW(reg);       // ?????,???????
  205.       for(i=0; i<bytes; i++)
  206.         SPI_RW(pBuf[i]);        // ??????nRF24L01
  207.       CSN = 1;                    // CSN??,??????
  208.       return(status);             // ???????
  209. }
  210. /**************************************************/

  211. /**************************************************
  212. ??:RX_Mode()

  213. ??:
  214.     ??????nRF24L01?????,????????????
  215. /**************************************************/
  216. void RX_Mode(void)
  217. {
  218.     CE = 0;
  219.       SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);  // ????????0??????????????
  220.       SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);               // ??????0????
  221.       SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);           // ??????0
  222.       SPI_RW_Reg(WRITE_REG + RF_CH, 40);                 // ??????0x40
  223.       SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH);  // ????0???????????????
  224.       SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);            // ?????1Mbps,????0dBm,????????
  225.       SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);              // CRC??,16?CRC??,??,????
  226.     delay_ms(150);
  227.       CE = 1;                                            // ??CE??????
  228. }
  229. /**************************************************/

  230. /**************************************************
  231. ??:TX_Mode()

  232. ??:
  233.     ??????nRF24L01?????,(CE=1????10us),
  234.     130us?????,???????,??????????
  235.     ?????????
  236. /**************************************************/
  237. void TX_Mode(uchar * BUF)
  238. {
  239.     CE = 0;
  240.       SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);     // ??????
  241.       SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);  // ????????,????0?????????
  242.       SPI_Write_Buf(WR_TX_PLOAD, BUF, TX_PLOAD_WIDTH);                  // ?????TX FIFO
  243.       SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);       // ??????0????
  244.       SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);   // ??????0
  245.       SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x0a);  // ????????250us+86us,????10?
  246.       SPI_RW_Reg(WRITE_REG + RF_CH, 40);         // ??????0x40
  247.       SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);    // ?????1Mbps,????0dBm,????????
  248.       SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);      // CRC??,16?CRC??,??
  249.     delay_ms(150);
  250.     CE = 1;
  251. }
  252. /**************************************************/

  253. /**************************************************
  254. ??:Check_ACK()

  255. ??:
  256.     ??????????????,?????????
  257.     ?????
  258. /**************************************************/
  259. uchar Check_ACK(bit clear)
  260. {
  261.     while(IRQ);
  262.     sta = SPI_RW(NOP);                    // ???????
  263.     if(TX_DS)
  264.     {
  265.         //blink(3);
  266.     }
  267.     //blink(5);
  268.     if(MAX_RT)
  269.         if(clear)                         // ????TX FIFO,???????MAX_RT???????
  270.             SPI_RW(FLUSH_TX);
  271.     SPI_RW_Reg(WRITE_REG + STATUS, sta);  // ??TX_DS?MAX_RT????
  272.     IRQ = 1;
  273.     if(TX_DS)
  274.         return(0x00);
  275.     else
  276.         return(0xff);
  277. }
  278. /**************************************************/

  279. /**************************************************
  280. ??:CheckButtons()

  281. ??:
  282.     ????????,??????????
  283. /**************************************************/
  284. void CheckButtons()
  285. {
  286.     P3 |= 0x00;
  287.     if(!(P3 & 0x01))                    // ??P3^0??
  288.     {
  289.         delay_ms(20);
  290.         if(!(P3 & 0x01))                // ??P3^0??
  291.         {
  292.             TX_BUF[0] = ~DATA;          // ??????
  293.             //TX_BUF[0] = 0xff;          // ??????
  294.             TX_Mode(TX_BUF);            // ?nRF24L01????????????            
  295.             //LED = ~DATA;                // ????LED??
  296.             Check_ACK(0);               // ??????,??TX FIFO
  297.             LED = 1;                    // ??LED
  298.             RX_Mode();                    // ???????
  299.             while(!(P3 & 0x01));
  300.             DATA <<= 1;
  301.             if(!DATA)
  302.                 DATA = 0x01;
  303.         }
  304.     }
  305. }
  306. /**************************************************/

  307. /*void blink(char i)
  308. {
  309.     while(i--)
  310.     {
  311.         LED = 1;
  312.         delay_ms(50);
  313.         LED = 0;
  314.         delay_ms(50);
  315.     }

  316. }*/

  317. /***********************
  318. 1602
  319. ***********************/
  320. void delay(uint z)        //短延时
  321. {
  322.         uint x,y;
  323.         for(x=z;x>0;x--)
  324.                 for(y=110;y>0;y--);
  325. }

  326. void write_com(uchar com)        //1602写命令子程序
  327. {
  328.         rs=0;                //RS是数据命令选择短,高电平写数据,低电平写命令
  329.         rd=0;                //RD是读写选择短,高电平读,低电平写
  330.         lcden=0;        //1602选通端,高电平选通,低电平禁止
  331.         LCDIO=com;
  332.         delay(5);
  333.         lcden=1;
  334.         delay(5);
  335.         lcden=0;       
  336. }

  337. void write_date(uchar date)        //1602写数据子程序
  338. {
  339.         rs=1;        //RS是数据命令选择短,高电平写数据,低电平写命令
  340.         rd=0;        //RD是读写选择短,高电平读,低电平写
  341.         lcden=0;        //1602选通端,高电平选通,低电平禁止
  342.         LCDIO=date;
  343.         delay(5);
  344.         lcden=1;
  345.         delay(5);
  346.         lcden=0;       
  347. }



  348. void init()                                //1602初始化程序
  349. {
  350.         uchar num;
  351.         lcden=0;

  352.         write_com(0x38);        //0011 1000B,功能模式设置,设置为8为数据口,两行显示,5*7点阵
  353.         write_com(0x0c);        //0000 1011B,显示开及光标设置,关显示,显示光标,光标闪烁
  354.         write_com(0x06);        //0000 0110B,显示光标移动设置,读或写一个字符,地址指针减一且光标减一,写一个字符屏幕显示不移动
  355.         write_com(0x01);        //0000 0001B,显示清屏,数据指针和所有显示清屏
  356.         write_com(0x80);        //1000 000B,关闭显示
  357.         delay(5);
  358.         write_com(0x80);        //1000 000B,设置为2行显示,写入第一行字符的地址,第一行地址是00-2F
  359.         for(num=0;num<16;num++)
  360.                 {
  361.                         write_date(table[num]);        //写入第一行数据
  362.                         delay(5);
  363.                 }
  364.         write_com(0x80+0x40);        //1100 0000B,设置为2行显示,写入第二行字符的地址,第而行地址是40-67
  365.         for(num=0;num<16;num++)        //写入第二行数据
  366.                 {
  367.                         write_date(table1[num]);//写入第二行数据
  368.                         delay(5);
  369.                 }      
  370.        

  371. }

  372. void ds1820disp()//温度值显示
  373.         { uchar flagdat;
  374.           disdata[0]=tvalue/1000+0x30;//百位数
  375.      disdata[1]=tvalue%1000/100+0x30;//十位数
  376.      disdata[2]=tvalue%100/10+0x30;//个位数
  377.      disdata[3]=tvalue%10+0x30;//小数位
  378.    
  379.      if(tflag==0)
  380.             flagdat=0x2b;//正温度不显示符号
  381.      else
  382.        flagdat=0x2d;//负温度显示负号:-

  383.      if(disdata[0]==0x30)
  384.            {disdata[0]=0x20;//如果百位为0,不显示
  385.                  if(disdata[1]==0x30)
  386.                   {disdata[1]=0x20;//如果百位为0,十位为0也不显示
  387.                   }
  388.                 }
  389.            write_com(0x80+2);            //1100 0000B,设置为2行显示,写入第二行字符的地址,第而行地址是40-67
  390.            write_date(flagdat);//显示符号位
  391.            write_com(0x80+3);
  392.            write_date(disdata[0]);//显示百位
  393.            write_com(0x80+4);
  394.            write_date(disdata[1]);//显示十位        
  395.            write_com(0x80+5);
  396.            write_date(disdata[2]);//显示个位        
  397.            write_com(0x80+6);
  398.            write_date(0x2e);//显示小数点        
  399.            write_com(0x80+7);
  400.            write_date(disdata[3]);//显示小数位
  401.            write_com(0x80+8);
  402.            write_date('C');
  403.    }

  404. void ADdisp()
  405.          {
  406.         long int shidu;
  407.   shidu=RX_BUF[3];
  408.         xiao=((shidu)*50*20/255)%10+0x30;
  409.         ge=((shidu)*50*20/255)%100/10+0x30;
  410.         shi=((shidu)*50*20/255)%1000/100+0x30;
  411.         bai=((shidu)*50*20/255)/1000+0x30;
  412.         if(bai==0x30)
  413.            {bai=0x20;//如果百位为0,不显示
  414.                  if(shi==0x30)
  415.                   {shi=0x20;//如果百位为0,十位为0也不显示
  416.                   }
  417.                 }
  418.   write_com(0x80+0x45);
  419.         write_date(0x2e);//显示小数点
  420.        
  421.        
  422.         write_com(0x80+0x46);
  423.         write_date(xiao);//显示小数位
  424.        
  425.        
  426.         write_com(0x80+0x44);
  427.         write_date(ge);//显示个位
  428.        
  429.        
  430.         write_com(0x80+0x43);
  431.         write_date(shi);//显示十位
  432.                  
  433.                  write_com(0x80+0x42);
  434.         write_date(bai);//显示百位
  435.                  
  436.        
  437.        
  438.         write_com(0x80+0x47);
  439.            write_date('%');
  440.     }
  441.          
  442.          read_temp()/*读取温度值并转换*/
  443. {  
  444.       a=RX_BUF[1];
  445.                         b=RX_BUF[2];
  446.   tvalue=b;
  447.   tvalue<<=8;
  448.   tvalue=tvalue|a;
  449.     if(tvalue<0x0fff)
  450.    tflag=0;
  451.     else
  452.    {tvalue=~tvalue+1;
  453.          tflag=1;
  454.    }
  455. f_temp=tvalue*(0.0625);// 温度在寄存器中为12位,分辨率为0.0625
  456. tvalue=f_temp*10+0.5;//乘以10表示小数点后面只取1位,加0.5时四舍五入
  457.        
  458.          return(tvalue);
  459.   }
  460. /**************************************************
  461. ??:main()

  462. ??:
  463.     ???
  464. /**************************************************/
  465. void baojing()
  466. {
  467.         if(tvalue>=280)
  468.         {
  469.                 beep=1;
  470.         write_com(0x80+0x4e);
  471.         write_date('!');
  472.                 write_com(0x80+0x4f);
  473.                 write_date('!');
  474.         }
  475.         else
  476.         {
  477.         beep=0;
  478.         write_com(0x80+0x4e);
  479.         write_date(0x20);
  480.                 write_com(0x80+0x4f);
  481.         write_date(0x20);
  482.         }
  483. }       
  484.        
  485. void main(void)
  486. {   
  487.           LED=1;
  488.           beep=0;
  489.     init_io();                      // ???IO
  490.           init();
  491.     RX_Mode();                      // ???????

  492.     while(1)
  493.     {

  494.         sta = SPI_Read(STATUS);      // ??????
  495.         //delay_ms(200);
  496.         if(RX_DR)                  // ?????????
  497.         {
  498.             SPI_Read_Buf(RD_RX_PLOAD, RX_BUF, TX_PLOAD_WIDTH);  // ?RX FIFO????
  499.             flag = 1;
  500.         }
  501.         SPI_RW_Reg(WRITE_REG + STATUS, sta);  // ??RX_DS????

  502.         if(flag)                   // ????
  503.         {
  504.             if(RX_BUF[0] == 1)
  505.             {   beep=0;
  506.                 LED=~LED;
  507.                                                           read_temp();
  508.                        ds1820disp();//显示
  509.                                                          baojing();          
  510.             }

  511.             if(key==0)
  512.             {
  513.                                                          ADdisp();
  514.             }
  515.             flag = 0;               // ???
  516.         }

  517.     }
  518. }
复制代码

所有资料51hei提供下载:
NRF24L01测温测湿.rar (105.22 KB, 下载次数: 36)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:400250 发表于 2020-4-5 17:08 | 显示全部楼层
感谢分享,最近正在做NRF24L01相关设计,值得参考!赞!
回复

使用道具 举报

ID:759890 发表于 2021-3-26 21:49 | 显示全部楼层
我还是没搞定这个,唉
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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