发 帖  
原厂入驻New
[问答] NRF24L01双向通信断线自动重连类似全双工怎么回事
80 nRF24L01 主机
分享
<p>                                         
下面是双向通信的基本原理和方法,只是说明大体结构,NRF函数是调用原子大哥的,简单容易理解;</p>
<p>#define Recon_Delay_Cnt 2     //重连延时计数,范围在1~255,值越大重连延时越大;也可以理解为是最大发送接收次数</p>
<p>u8 Tx_Cnt=0;         //发送次数计数<br />
u8 Rx_Cnt=0;         //接收次数计数<br />
u8 NRF24l01_Mode=0;        //0表示发送模式,1表示接收模式<br />
u8 tmp_buf_Tx[32],tmp_buf_Rx[32];   //发送接收缓冲数组</p>
<p>NRF24L01_TX_Mode();<br />
while(1)       //NRF24L01工作在一个无限循环体内<br />
{         <br />
        IF (NRF24L01_Mode==0)<br />
       {  <br />
            tmp_buf_Tx[0]=0x11;     <br />
            if (NRF24L01_TxPacket(tmp_buf_Tx)==TX_OK)<br />
            {     <br />
               Tx_Cnt=0;<br />
               NRF24L01_Mode=1;<br />
               NRF24L01_RX_Mode();   //一旦发送成功则变成接收模式;<br />
            }   <br />
           Tx_Cnt++;<br />
           if (Tx_Cnt==Recon_Delay_Cnt) //如果连续发送Recon_Delay_Cnt次都失败,则切换为接收模式<br />
           {       <br />
               Tx_Cnt=0;<br />
               NRF24L01_Mode=1;<br />
               NRF24L01_RX_Mode();<br />
           }<br />
       }<br />
       else<br />
      {<br />
           if (NRF24L01_RxPacket(tmp_buf_Rx)==0)//一旦接收成功则变成发送模式;<br />
          {<br />
              Rx_Cnt=0;<br />
              NRF24L01_Mode=0;<br />
              NRF24L01_TX_Mode();<br />
          }<br />
          Rx_Cnt++;<br />
          if (Rx_Cnt==Recon_Delay_Cnt)//如果连续接收Recon_Delay_Cnt次都失败,则切换为发送模式<br />
          {<br />
               Rx_Cnt=0;<br />
               NRF24L01_Mode=0;<br />
               NRF24L01_TX_Mode();<br />
          }<br />
      } <br />
delay_ms(10);   //延时大发送接收慢,延时小发送接收快,太小了可能影响通信可靠性;<br />
}</p>
<p>说明:测试通过,并且应用到我的小四轴上了;<br />
测试条件:原子的开发板,一个STM32f103c8t6最小系统;<br />
测试时利用上面的程序进行如下修改;<br />
         原子开发板部分:程序和上面的一样;<br />
         最小系统部分:延时变为delay_ms(2);取消了断线重连功能,因为只有有一端有这个功能就会连接成功;<br />
         程序如下:<br />
u8 NRF24L01_Mode=1;         <br />
NRF24L01_RX_Mode();         <br />
while(1)       //NRF24L01工作在一个无限循环体内<br />
{         <br />
        if (NRF24L01_Mode==0)<br />
        {  <br />
              tmp_buf_Tx[0]=0x11;     <br />
              if (NRF24L01_TxPacket(tmp_buf_Tx)==TX_OK)<br />
              {     <br />
                   NRF24L01_Mode=1;<br />
                   NRF24L01_RX_Mode();   //一旦发送成功则变成接收模式;<br />
              }     <br />
         }<br />
        else<br />
        {<br />
              if (NRF24L01_RxPacket(tmp_buf_Rx)==0)//一旦接收成功则变成发送模式;<br />
              {<br />
                   NRF24L01_Mode=0;<br />
                   NRF24L01_TX_Mode();<br />
              }<br />
        } <br />
delay_ms(2);   //延时大发送接收慢,延时小发送接收快,太小了可能影响通信可靠性;<br />
}<br />
原理分析:为方便分析,将第一段程序称为主机,第二段程序称为从机。<br />
首先明白,不过主机还是从机,都有一个共性,就是一旦接收或发送成功则立即切换模式;<br />
区别是,从机只有在接收或发送成功后才切换模式,不然的话会一直处于当前模式下,无法切换;<br />
对于主机来说,从机的这个特性恰好符合主机达到最大发送接收次数的自动模式切换;<br />
到底怎么个符合呢?</p>
<p>下面举例说明:<br />
正常情况下,主机成功发送一个数据包,立即变成接收模式,从机成功接收到数据包,立即变成发送模式;这样就双向通信;<br />
异常情况下,外界干扰,或者本身延时导致时间上的不匹配,可能主机和从机都变成了接收模式,这时数据停止传输,从机的模式无法切换;<br />
但是当主机达到最大接收次数后,则切换为发送模式,此时从机就可以接收数据了;同时变成发送模式也一样的;             </p>
NRF34L01双向通信.rar (1.52 KB )
0
2020-6-16 19:53:31   评论 分享淘帖 邀请回答

相关问题

42个回答
不错,我以前做无线通信的时候为了保证发送或接受成功直接这样用while(!(NRF24L01_TxPacket(tmp_buf_Tx)==TX_OK));
2020-6-17 06:36:16 评论

举报

你这是用一个通道。这方法确实可行,不过感觉浪费时间,012345通道都可以应答通讯,何不好好利用,发射的地址是和0通道绑定的,可以这样通讯,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 甲乙2模块:甲(发0通道对应乙收5通道应答通讯)《甲发射数据给乙(应答模式)》<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;乙(发0通道对应甲收5通道应答通讯)《乙发射数据给甲(应答模式)》<br />
收发模式切换用:甲先发射模式,发射成功立刻切换接收模式。发射不成功1秒后切换接收模式。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;乙先发射模式,发射成功立刻切换接收模式。发射不成功1.5秒后切换接收模式。<br />
如果成功对接了,那这2模块通讯效率应该最高。(0x00寄存器bit0切换非常快。)
2020-6-17 06:52:33 评论

举报

<br>请问甲模块和乙模块的寄存器具体怎么配置?
2020-6-17 07:04:32 评论

举报

甲模块0:
<br>const&nbsp;u8&nbsp;&nbsp;ip[6]={'5','F','U','C','K',0x00};//发射地址&nbsp;&nbsp;那个0x00用于LCD函数结束显示
<br>const&nbsp;u8&nbsp;ip0[6]={'5','F','U','C','K',0x00};//接收地址0&nbsp;我调了2天
<br>const&nbsp;u8&nbsp;ip1[6]={'1','F','U','C','K',0x00};//接收地址1&nbsp;才发现低位在前,高位在后。
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//(低位优先,写的时候低位写到高位,读的时候低位先被读出)
<br>const&nbsp;u8&nbsp;ip2[6]={'2','F','U','C','K',0x00};//接收地址2&nbsp;地址char5,char4,char3,char2,char1.
<br>const&nbsp;u8&nbsp;ip3[6]={'3','F','U','C','K',0x00};//接收地址3        通道2345只能设置char1
<br>const&nbsp;u8&nbsp;ip4[6]={'4','F','U','C','K',0x00};//接收地址4        写的时候顺序是char1,char2,char3,char4,char5
<br>const&nbsp;u8&nbsp;ip5[6]={'0','F','U','C','K',0x00};//接收地址5       
<br>乙模块1:
<br>const&nbsp;u8&nbsp;&nbsp;ip[6]={'0','F','U','C','K',0x00};//发射地址&nbsp;&nbsp;那个0x00用于LCD函数结束显示
<br>const&nbsp;u8&nbsp;ip0[6]={'0','F','U','C','K',0x00};//接收地址0&nbsp;我调了2天
<br>const&nbsp;u8&nbsp;ip1[6]={'6','F','U','C','K',0x00};//接收地址1&nbsp;才发现低位在前,高位在后。
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//(低位优先,写的时候低位写到高位,读的时候低位先被读出)
<br>const&nbsp;u8&nbsp;ip2[6]={'7','F','U','C','K',0x00};//接收地址2&nbsp;地址char5,char4,char3,char2,char1.
<br>const&nbsp;u8&nbsp;ip3[6]={'8','F','U','C','K',0x00};//接收地址3        通道2345只能设置char1
<br>const&nbsp;u8&nbsp;ip4[6]={'9','F','U','C','K',0x00};//接收地址4        写的时候顺序是char1,char2,char3,char4,char5
<br>const&nbsp;u8&nbsp;ip5[6]={'5','F','U','C','K',0x00};//接收地址5       
<br>收发模式切换用:甲先发射模式,发射成功立刻切换接收模式。发射不成功1秒后切换接收模式。
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;乙先发射模式,发射成功立刻切换接收模式。发射不成功1.5秒后切换接收模式。
<br>收发模式切换改0x00寄存器的(bit0)
2020-6-17 07:19:03 评论

举报

<br>发送不成功要延时1s才切换模式,难道不浪费时间?
2020-6-17 07:34:32 评论

举报

<br>你给的是地址寄存器,配置寄存器怎么设置?
2020-6-17 07:47:24 评论

举报

<br>你要是不能理解的话,你调下单向,乙发射,甲的通道5接收,应答模式。你会发现不一定非要甲的通道0接收。还有NRF24L01的例程都是P0对P0你们都被这例程给误导了。当你学会012345通道的应答全开和应答的部分通道开启,你会学到一些想法。还有手册也有一些误导性,这不是手册的问题,这是自己误导自己。原因是通道2345写地址实际是低字节先写。所以只要写1次。比如'0','F','U','C','K'实际是'K','C','U','F','0'我对24L01模块痴迷过,为了调通通道熬夜到2点才睡。我买的模块是NRF24L01+带PA可以1100米。和24L01有一点区别250kps和多几个寄存器设置,(比如低字发到高字(就是你常用的0xA0),或高字发到低字)你可以看下我写的帖子就在这论坛里。
2020-6-17 08:06:20 评论

举报

<br>比如说发送模式的初始化,接收模式的初始化怎么设置的?
2020-6-17 08:15:59 评论

举报

<br>发送不成功要延时1s才切换模式,难道不浪费时间?&nbsp;&nbsp;&nbsp;。。。是开机刚对机的那一刻,我问你,你开甲机后能在1秒钟内开乙机?你好像还没明白这逻辑关系。比如信号不好时(或其中一个断电,断网,受干扰)另一机会有个寄存器0x08和0x07设置的原因。我才考虑甲机1秒,乙机1.5秒,想让它们有足够的时间对机能对上。你多多仿真试验一下,甲发射,乙接收,乙不清空接收数据,甲永远收不到应答,永远发送失败,对于遥控飞机控制的这情况发射机的发射通道不要用应答模式,等你发射机收到应答再发射命令去控制,飞机早撞了(信号不好的情况下)你想下250kbs发射32字节要多长时间加上设备各种延时,就是你可以设置的最快对机时间。不一定要1秒。2机必须要有时间差,甲乙2机同时开,1秒1变化,假设同时发射,同时接收,就永远对不上。(对不上的概率很小,但设计者应该程序设计完美)对机完成后就是这2模块最快的双向通信速度了。此时那1秒切换收发就彻底没用了,除非因信号不好再次断网,才用到。
2020-6-17 08:27:33 评论

举报

<br />
比如说发送模式的初始化,接收模式的初始化怎么设置的?。。。我的兲啊,你编程序从来不看手册的么?虽然我也是抄的原子的程序改改,到现在SPI也没彻底弄明白,只学着调用函数。我把手册发给你,你看了就知道怎么去设置24L01初始化了,你找找帖子,24L01模块6通道接收的。里面有我调试好的mini板的程序012345通道全用。STM32W无线射频ZigBee单片机原理与应用.pdf (2.64 MB )
NRF24L01_中文.pdf (890.66 KB )
2020-6-17 08:43:10 评论

举报

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <center></center><br />
<center></center><br />
2020-6-17 08:58:17 评论

举报

<br>你看看我的对不对
<br>我只用了P0,和P1通道
2020-6-17 09:15:07 评论

举报

我刚才回复你时想了个简单让你明白的结构图,你画个长方形模块,
<br>甲012345
<br>乙012345
<br>丙012345
<br>x012345
<br>y012345
<br>牛012345
<br>B012345
<br>。
<br>。
<br>你用导线连这些012345可以组成你想要的网络。比如(发射机只能用0发射,甲发射给x),(x的2接收,x的0发射给乙),(乙的4接收,乙的0发射给丙),(丙的2接收,丙的0发射给甲的3)这是环形网络。星型的是:甲用0发射不应答,无数个接收机接收。你也可以组个特别复杂的网络。方法和上面一样。
2020-6-17 09:29:31 评论

举报

你QQ多少,我们可以好好交流,我QQ750273008不过我已经学会NRF24L01+模块了(1100米),我想学物联网,看了cc2530感觉垃圾,看好stm32w的无线模块(主要原因它可以3700米传输数据,才100mw)期待原子哥出个stm32w的开发板。已经找到stm32w的中文手册了《STM32W无线射频ZigBee单片机原理与应用》我郁闷啊,不知道物联网是什么概念。所有感应模块连起来给主机处理就是物联网?自组网也不知道,好像和家里wifi无线差不多吧,收到无线,密码正确就连起来通讯。目前只找到stm32w开发板就一家做,期待原子哥出个开发板教我们。。。。。
2020-6-17 09:42:11 评论

举报

<br>我如果用上面的程序测试,是不对的,即使一端断电,另一端还是有接收到数据的信号
2020-6-17 09:57:17 评论

举报

2020-6-17 10:14:50 评论

举报

<br>比如说发送模式的初始化,接收模式的初始化怎么设置的?。。。我的兲啊!!!0x01寄存器设置0x3f;0x02设置0x3f;对应通道地址设置,对应通道的有效字节数设置。你去看我发的帖子就知道了。帖子里还有编好的程序,下载就能用。
2020-6-17 10:30:14 评论

举报

<br>我只用通道P1作为应答,为什么要使能所有的通道?
2020-6-17 10:44:35 评论

举报

http://www.openedv.com/posts/list/0/15438.htm?privmsg=1#117732
<br>和
<br>
<br>http://www.openedv.com/posts/list/0/15693.htm?privmsg=1#109104
2020-6-17 10:53:59 评论

举报

只有小组成员才能发言,加入小组>>

123下一页

106个成员聚集在这个小组

加入小组

热门话题

创建小组步骤

关闭

站长推荐 上一条 /7 下一条

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