找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1574|回复: 4
收起左侧

单片机+NRF24L01+模块遇到的问题,工作一段时间后接收端异常

[复制链接]
ID:627044 发表于 2019-10-20 15:58 | 显示全部楼层 |阅读模式
各位大神,我在用NRF24L01+模块时遇到一个问题,就是模块工作一段时间后接收端就不能正常工作了,需要重启接收端NRF24L01+模块才能恢复工作。               这个是接收端单片机程序
  1. #include<reg52.h>
  2. #include<api.h>
  3. #include<intrins.h>
  4. #include <DS18B20.h>
  5. #include<lcd12864.h>
  6. #define uchar unsigned char
  7. #define uint unsigned int
  8. #define TX_ADR_WIDTH    5   // 5 bytes TX(RX) address width
  9. #define TX_PLOAD_WIDTH  10  // 20 bytes TX payload

  10. uchar const TX_ADDRESS[TX_ADR_WIDTH]  = {0x34,0x43,0x10,0x10,0x01}; // Define a static TX address

  11. uchar rx_buf[TX_PLOAD_WIDTH];
  12. uchar tx_buf[TX_PLOAD_WIDTH];
  13. /**************************************************/
  14. sbit CE =  P1^2;
  15. sbit CSN=  P1^3;
  16. sbit SCK=  P1^7;
  17. sbit MOSI= P1^5;
  18. sbit MISO= P1^6;
  19. sbit IRQ = P1^4;
  20. /**************************************************/
  21. uchar         bdata sta;
  22. sbit        RX_DR        =sta^6;
  23. sbit        TX_DS        =sta^5;
  24. sbit        MAX_RT        =sta^4;        
  25. /**************************************************/
  26. sbit JDQ = P2^0;
  27. uint temperature;
  28. //NRF24L01+

  29. void delayus(uint z)
  30. {
  31.         while(z!=0) z--;
  32. }
  33. uchar SPI_RW(uchar dat)//写一字节并读出此地址的状态
  34. {
  35.          uchar i;
  36.         for(i=0;i<8;i++)
  37.         {
  38.                 SCK=0;
  39.                 MOSI=(dat & 0x80);
  40.                 dat<<=1;
  41.                 SCK=1;
  42.                 dat|=MISO;               
  43.         }
  44.         SCK=0;           //拉低时钟保持通信状态
  45.         return dat;
  46. }
  47. uchar SPI_RW_Reg(uchar reg,value)//写一字节并读出此地址的状态
  48. {
  49.          uchar status;
  50.         CSN=0;
  51.         status=SPI_RW(reg);
  52.         SPI_RW(value);
  53.         CSN=1;
  54.         return status;
  55. }
  56. uchar SPI_Read(uchar reg)  //读一字节
  57. {
  58.         uchar value;
  59.         CSN=0;
  60.         SPI_RW(reg);
  61.         value=SPI_RW(0);
  62.         CSN=1;
  63.         return value;
  64. }
  65. uchar SPI_Read_Buf(uchar reg,uchar *pBuf,uchar uchars)//读多个字节并读出此地址的状态
  66. {
  67.         uchar status,i;
  68.         CSN=0;
  69.         status=SPI_RW(reg);
  70.         for(i=0;i<uchars;i++)
  71.         pBuf[i]=SPI_RW(0);
  72.         CSN=1;
  73.         return status;        
  74. }
  75. uchar SPI_write_Buf(uchar reg,uchar *pBuf,uchar uchars)//写多个字节并读出此地址的状态
  76. {
  77.         uchar status,i;
  78.         CSN=0;
  79.         status=SPI_RW(reg);
  80.         for(i=0;i<uchars;i++)
  81.         SPI_RW(*pBuf++);
  82.         CSN=1;
  83.         return status;
  84. }/*
  85. void nrf24l01_TXBUF(uchar *tx_buf) //发送tx_buf中的数据
  86. {
  87.         CE=0;//停止射频工作
  88.         SPI_write_Buf(0x20+10,0x01,5);//写本机地址
  89.         SPI_write_Buf(0x20+10,0x01,5);//装载接收端O通道地址
  90.         SPI_write_Buf(0xa0,tx_buf,2);//装载要发送的数据
  91.         SPI_RW_Reg(0x20+0x00,0x0e);//IRQ收发完成中断响应16位CRC,发送模式
  92.         CE=1; //置高CE,激发数据发射
  93.         delay(1);
  94. } */
  95. void nrf24l01_init()
  96. {
  97.         CE=0;
  98.         CSN=1;
  99.         SCK=0;
  100.         IRQ=1;
  101.         delayus(15);
  102. }
  103. void setRX_Mode()
  104. {
  105.         CE=0;
  106.           SPI_write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 写接收地址到0通道
  107.           SPI_RW_Reg(WRITE_REG + EN_AA, 0x00);      // Enable Auto.Ack:Pipe0
  108.           SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  // Enable Pipe0
  109.           SPI_RW_Reg(WRITE_REG + RF_CH,40);        // Select 工作频段 channel 2.4G
  110.           SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH); // Select same RX payload width as TX Payload width
  111.           SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);   // TX_PWR:0dBm, Datarate:2Mbps, LNA:HCURR
  112.           SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);     //IRQ中断响应16位CRC校验,接收模式

  113.           CE = 1; // Set CE pin high to enable RX device
  114.         delayus(35);
  115. }
  116. bit nRF24L01_RxPacket(uchar *rx_buf)
  117. {
  118.         bit flag=0;
  119.         sta=SPI_Read(STATUS);        // read register STATUS's value
  120.         if(RX_DR)                                // if receive data ready (RX_DR) interrupt
  121.         {
  122.                 SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer
  123.                 flag=1;
  124.                 SPI_RW_Reg(WRITE_REG+STATUS,0xff);//清空状态寄存器
  125.         }               
  126.         return flag;
  127. }
  128. void DS18B20_dis()
  129. {
  130.         lcd_dis(0,4,uchartostr(rx_buf[0]));
  131.         lcd_dis(0,5,".");
  132.         lcd_dis(0,6,uchartostr(rx_buf[1]));
  133.         lcd_dis(0,7,"℃");        
  134. }
  135. void DS1302_dis()
  136. {
  137.         lcd_dis(2,3,DS1302tostr(rx_buf[2]));
  138.         lcd_dis(2,4,":");
  139.         lcd_dis(2,5,DS1302tostr(rx_buf[3]));
  140.         lcd_dis(2,6,":");
  141.         lcd_dis(2,7,DS1302tostr(rx_buf[4]));
  142. //switch(rx_buf[2])
  143. //{
  144. //case 1: JDQ = 0; lcd_dis(2,4,"开");break; //定时脉冲宽度;
  145. //case 2: JDQ = 1; lcd_dis(2,5,"关");break; //补充5ms;
  146. //}               
  147.                         
  148. }
  149. uchar ds2_dis[2];
  150. void DS18B20_dis2()
  151. {        
  152.         if(ds_reset())
  153.         {
  154.                 temperature=get_temperature();
  155.                 ds2_dis[0]=temperature/10;
  156.                 ds2_dis[1]=temperature%100%10;
  157.                 lcd_dis(1,4,uchartostr(ds2_dis[0]));
  158.                 lcd_dis(1,5,".");
  159.                 lcd_dis(1,6,uchartostr(ds2_dis[1]));
  160.                 lcd_dis(1,7,"℃");
  161.         }
  162.         else
  163.         {        
  164.                 lcd_dis(1,4,"无硬件!");               
  165.         }
  166. }  
  167. void main()
  168. {
  169.         uchar i=0;
  170.         uchar buf0[5]={0,0,0,0,0};
  171.         lcd_init();
  172.         nrf24l01_init();
  173.         setRX_Mode();
  174.         SPI_Read_Buf(READ_REG+RX_ADDR_P0,buf0,TX_PLOAD_WIDTH);
  175.         delay(100);
  176.         lcd_dis(0,0,"RX_ADDR_P0:");
  177.         lcd_dis(1,0,uchartostr(buf0[0]));
  178.         lcd_dis(1,2,uchartostr(buf0[1]));
  179.         lcd_dis(1,4,uchartostr(buf0[2]));
  180.         lcd_dis(1,6,uchartostr(buf0[3]));
  181.         lcd_dis(2,0,uchartostr(buf0[4]));
  182.         delay(1000);
  183.         while(1)
  184.         {        
  185.                 if(nRF24L01_RxPacket(rx_buf))
  186.                 {
  187.                                         lcd_wcmd(0x01);      //清除LCD的显示内容
  188.                                         delay(5);
  189.                                         lcd_dis(0,0,"室外温度");
  190.                                         lcd_dis(1,0,"室内温度");
  191.                                         lcd_dis(2,0,"时间:");//显示提示符
  192.                                         lcd_dis(3,1,"2.4G无线测试");
  193.                         DS18B20_dis();
  194.                         DS1302_dis();
  195.                         DS18B20_dis2();
  196.                         delay(910);
  197.                 }else
  198.         {delay(5);lcd_dis(0,4,"无信息!");delay(800);}
  199.         }               
  200. }




  201. 发射端程序
  202. #include <reg52.h>
  203. #include <intrins.h>
  204. #include <api.h>
  205. #include <DS18B20.h>
  206. #include <DS1302.h>
  207. #define uchar unsigned char
  208. #define uint unsigned int
  209. #define TX_ADR_WIDTH    5   // 5 bytes TX(RX) address width
  210. #define TX_PLOAD_WIDTH  10  // 20 bytes TX payload

  211. uchar const TX_ADDRESS[TX_ADR_WIDTH]  = {0x34,0x43,0x10,0x10,0x01}; // Define a static TX address

  212. //uchar rx_buf[TX_PLOAD_WIDTH];
  213. uchar tx_buf[TX_PLOAD_WIDTH];
  214. /**************************************************/
  215. sbit CE =  P1^2;
  216. sbit CSN=  P1^3;
  217. sbit SCK=  P1^7;
  218. sbit MOSI= P1^5;
  219. sbit MISO= P1^6;
  220. sbit IRQ = P1^4;
  221. /**************************************************/
  222. uchar         bdata sta;
  223. sbit        RX_DR        =sta^6;
  224. sbit        TX_DS        =sta^5;
  225. sbit        MAX_RT        =sta^4;        
  226. //uchar str[4];//uchartostr函数转换的字符串
  227. sbit K = P3^0;sbit G = P3^1;
  228. uint temperature;
  229. /*uchar RXaddr[5]={0x20,0x20,0x03,0x04,0x05};
  230. uchar TXaddr[5]={0x20,0x20,0x03,0x04,0x05};
  231. uchar const TXdat[]={0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
  232. 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
  233. 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,};*/
  234. /*uchar *uchartostr(uchar num)        //将一个字节的数据转换为字符串
  235. {
  236.         uchar x2,x1,x0,i;
  237.         x2=num/100;
  238.         x1=num%100/10;
  239.         x0=num%100%10;
  240.         i=0;
  241.         if(x2!=0)
  242.         {
  243.                 str[i]=x2+48;
  244.                 i++;
  245.         }
  246.         if(x1!=0)
  247.         {
  248.                 str[i]=x1+48;
  249.                 i++;
  250.         }
  251.         str[i]=x0+48;
  252.         i++;
  253.         str[i]='\0';
  254.         return str;
  255. }*/
  256. //NRF24L01+
  257. uchar SPI_RW(uchar dat)//写一字节并读出此地址的状态
  258. {
  259.          uchar i;
  260.         for(i=0;i<8;i++)
  261.         {               
  262.                 MOSI=(dat & 0x80);
  263.                 dat<<=1;
  264.                 SCK=1;
  265.                 dat|=MISO;
  266.                 SCK=0;               
  267.         }
  268.         return dat;
  269. }
  270. uchar SPI_RW_Reg(uchar reg,value)//写一字节并读出此地址的状态
  271. {
  272.          uchar status;
  273.         CSN=0;
  274.         status=SPI_RW(reg);
  275.         SPI_RW(value);
  276.         CSN=1;
  277.         return status;
  278. }
  279. uchar SPI_Read(uchar reg)  //读一字节
  280. {
  281.         uchar value;
  282.         CSN=0;
  283.         SPI_RW(reg);
  284.         value=SPI_RW(0);
  285.         CSN=1;
  286.         return value;
  287. }
  288. //read buffer!
  289. /*uchar SPI_Read_Buf(uchar reg,uchar *pBuf,uchar uchars)//读多个字节并读出此地址的状态
  290. {
  291.         uchar status,i;
  292.         CSN=0;
  293.         status=SPI_RW(reg);
  294.         for(i=0;i<uchars;i++)
  295.         pBuf[i]=SPI_RW(0);
  296.         CSN=1;
  297.         return status;        
  298. }*/
  299. uchar SPI_write_Buf(uchar reg,uchar *pBuf,uchar uchars)//写多个字节并读出此地址的状态
  300. {
  301.         uchar status,i;
  302.         CSN=0;
  303.         status=SPI_RW(reg);
  304.         for(i=0;i<uchars;i++)
  305.         SPI_RW(*pBuf++);
  306.         CSN=1;
  307.         return status;
  308. }
  309. void nrf24l01_TxPacket(uchar *tx_buf) //发送tx_buf中的数据
  310. {
  311.         CE=0;//停止射频工作
  312.         SPI_write_Buf(WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH);//写本机地址
  313.         SPI_write_Buf(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH);//装载接收端O通道地址
  314.         SPI_write_Buf(WR_TX_PLOAD,tx_buf,TX_PLOAD_WIDTH);//装载要发送的数据
  315.         SPI_RW_Reg(WRITE_REG+CONFIG,0x0e);//IRQ收发完成中断响应16位CRC,发送模式
  316.         CE=1; //置高CE,激发数据发射
  317.         delay(1);
  318. }
  319. void nrf24l01_init()
  320. {
  321.         delay(1);
  322.         CSN=1;
  323.         SCK=0;
  324.         IRQ=1;
  325.         CE=0;   
  326.         //SPI_write_Buf(0x30,TXaddr,5);
  327.         //SPI_Read_Buf(0x10,RXaddr,5);
  328.         SPI_RW_Reg(WRITE_REG+EN_AA,0x00);//频道0自动ACK
  329.         SPI_RW_Reg(WRITE_REG+SETUP_RETR,0x00);//禁止自动重发
  330.         SPI_RW_Reg(WRITE_REG+EN_RXADDR,0x01);//允许接收地址只有通道0
  331.         SPI_RW_Reg(WRITE_REG+RF_CH,40); //设置信道工作频率为2.4GHZ。收发必须一致        
  332.         SPI_RW_Reg(WRITE_REG+RX_PW_P0,TX_PLOAD_WIDTH); //设置接收数据长度
  333.         SPI_RW_Reg(WRITE_REG+RF_SETUP,0x07);//发射速率为2MHZ,发射功率为最大值0db
  334. }
  335. void DSdat_tostr()
  336. {
  337.         temperature=get_temperature();
  338.         tx_buf[0]=temperature/10;
  339.         tx_buf[1]=temperature%100%10;
  340. }
  341. void Read_DS1302_Dat()
  342. {
  343.         uchar hour,minute,second;
  344.         write_1302(0x8e,0x00);
  345.         
  346.         hour=read_1302(0x85);
  347.         
  348.         minute=read_1302(0x83);
  349.         
  350.         second=read_1302(0x81);        

  351.         write_1302(0x8e,0x80);
  352.         tx_buf[2]=hour;
  353.         tx_buf[3]=minute;
  354.         tx_buf[4]=second;        
  355. }
  356. void main()
  357. {
  358.         nrf24l01_init();
  359.         ds1302_init();
  360.         while(1)
  361.         {        if(K ==0)tx_buf[2]=1;
  362.             if(G ==0)tx_buf[2]=2;
  363.                 DSdat_tostr();
  364.                 Read_DS1302_Dat();
  365.                 SPI_RW_Reg(WRITE_REG+STATUS,0xff); //清除状态寄存器
  366.                 nrf24l01_TxPacket(tx_buf);        //进行一次发送操?
  367.                 delay(400);
  368.                 }
  369. }

复制代码


回复

使用道具 举报

ID:98195 发表于 2019-10-20 18:30 来自手机 | 显示全部楼层
我也遇到这种情况,要不是发送端要不是接收端需要重启  楼主解决了和我分享一下
回复

使用道具 举报

ID:351097 发表于 2019-10-21 09:26 | 显示全部楼层
检查一下系统的电源是否正常,输出电流是否足够。
回复

使用道具 举报

ID:627044 发表于 2019-10-21 19:23 | 显示全部楼层
丶念 发表于 2019-10-20 18:30
我也遇到这种情况,要不是发送端要不是接收端需要重启  楼主解决了和我分享一下

是接收端要重启,发送端不用
回复

使用道具 举报

ID:627044 发表于 2019-10-21 19:25 | 显示全部楼层
没有你 发表于 2019-10-21 09:26
检查一下系统的电源是否正常,输出电流是否足够。

用的是1A电流输出
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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