搜索
bottom↓
回复: 7

求助 关于NRF24L01 数据丢失问题

[复制链接]

出0入0汤圆

发表于 2014-4-26 10:56:59 | 显示全部楼层 |阅读模式
最近在做两轮小车,想用2401发送小车运行的一些数据,用来检测和调试。基本通讯完成,但是会有数据丢失 ,苦寻无果特来发帖讨教!!

1.发射端 TX
        void TX_Mode(void)                //模式设定
  {                                                                                                                 
        Clr_NRF24L01_CE;         //拉低CE
        NRF24L01_Write_Buf(NRF24L01_WRITE_REG+TX_ADDR,(u8*)TX_ADDRESS,TX_ADR_WIDTH);//写发送地址 本地地址 5字节的地址宽度
        NRF24L01_Write_Buf(NRF24L01_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH); //设置通道0接收地址  5字节地址宽度
       
        NRF24L01_Write_Reg(NRF24L01_WRITE_REG+EN_AA,0x01);     //使能通道0的自动应答    寄存器地址0x01
        NRF24L01_Write_Reg(NRF24L01_WRITE_REG+EN_RXADDR,0x01); //接收数据通道0容许           用于应答                寄存器地址0x02
        NRF24L01_Write_Reg(NRF24L01_WRITE_REG+SETUP_RETR,0xf0);//设置自动重发间隔时间:4000us + 86us;最大自动重发次数:15次
       
        NRF24L01_Write_Reg(NRF24L01_WRITE_REG+RF_CH,0x6e);       // 设置信道工作为2.5GHZ,收发必须一致
        NRF24L01_Write_Reg(NRF24L01_WRITE_REG+RF_SETUP,0x0f);  //设置发射速率为2MHZ,发射功率为最大值0dB        低噪声放大器增益
       
        NRF24L01_Write_Reg(NRF24L01_WRITE_REG+CONFIG,0x0e);
  }
发送数据函数:       
        u8 NRF24L01_TxPacket(u8 *txbuf)
{
        u8 sta;  
        Clr_NRF24L01_CE;                        //拉低CE装载数据
        NRF24L01_Write_Buf(NRF24L01_WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);  //写数据到TX BUF  32个字节
        NRF24L01_Write_Reg(NRF24L01_WRITE_REG+CONFIG,0x0e);                        //配置状态寄存器
        Set_NRF24L01_CE;                        // 升高启动发送          
        while(NRF24L01_IRQ!=0);                  //等待IRQ中断示意发送完成       
       
        sta=NRF24L01_Read_Reg(STATUS);  //读取状态寄存器的值          
        NRF24L01_Write_Reg(NRF24L01_WRITE_REG+STATUS,0xff); //清除TX_DS或MAX_RT中断标志 写1清楚中断
        if(sta&MAX_TX)//达到最大重发次数
                {
                NRF24L01_Write_Reg(NRF24L01_FLUSH_TX,0xff);                //清除TX FIFO寄存器
                LED0=0;                        //此段代码用以数据丢失LED反馈显示
                delay_ms(15);
                LED0=1;
                delay_ms(15);
                return MAX_TX;
                }
        if(sta&TX_OK)//发送完成
                {
                LED1=0;                        //此段代码用以数据丢失LED反馈显示
                delay_ms(5);
                LED1=1;
                delay_ms(5);
                return TX_OK;
                }
        return 0xff;//其他原因发送失败       
}

发送端主函数:
        int main(void)
{
         u8 Tx_Buf1[32];
        int data=0;
         
        SystemInit();                          //系统时钟初始化为72M          SYSCLK_FREQ_72MHz
        delay_init(72);                             //延时函数初始化          
        NVIC_Configuration();                  //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
        LED_Init();                                //LED端口初始化
          uart_init(9600);                        //串口初始化为9600
        NRF24L01_Init();                        //初始化2401
        while (NRF24L01_Check())        //检验是读写否运行正常        器件正常返回0,非正常返回1
        {
                LED0=0;
                delay_ms(300);
                LED0=1;
                delay_ms(300);
        }
        TX_Mode();                        //发送模式        
        while(1)                        //不停地发送0~99
                {
                        data++;
                        if(data==100)
                        data=0;
                        Tx_Buf1[1]=data;
                        NRF24L01_TxPacket(Tx_Buf1);        // 发送命令数据
                }
}

接收端配置函数:
void RX_Mode(void)
        {
        Clr_NRF24L01_CE;          
        NRF24L01_Write_Buf(NRF24L01_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH);//写RX节点地址
       
        NRF24L01_Write_Reg(NRF24L01_WRITE_REG+EN_AA,01);                    //使能通道0的自动应答   
        NRF24L01_Write_Reg(NRF24L01_WRITE_REG+EN_RXADDR,0x01);        //使能通道0的接收地址           
        NRF24L01_Write_Reg(NRF24L01_WRITE_REG+RF_CH,0x6e);                //设置RF通信频率                2.5G~  wifi干扰??  
        NRF24L01_Write_Reg(NRF24L01_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);        //选择通道0的有效数据宽度             
        NRF24L01_Write_Reg(NRF24L01_WRITE_REG+RF_SETUP,0x0f);                //设置TX发射参数,0db增益,2Mbps,低噪声增益开启   
        NRF24L01_Write_Reg(NRF24L01_WRITE_REG+CONFIG, 0x0f);                //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式
        Set_NRF24L01_CE;                         //CE为高,进入接收模式
        }
判断数据到达读取处理函数:
u8 NRF24L01_RxPacket(u8 *rxbuf)
{
        u8 sta;                                                                                 
        sta=NRF24L01_Read_Reg(STATUS);                                         //读取状态寄存器的值             
        NRF24L01_Write_Reg(NRF24L01_WRITE_REG+STATUS,sta);         //清除TX_DS或MAX_RT中断标志
        if(sta&RX_OK)//接收到数据
        {
                Clr_NRF24L01_CE;                //CE置低
                NRF24L01_Read_Buf(NRF24L01_RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);                //读取数据
                NRF24L01_Write_Reg(NRF24L01_FLUSH_RX,0xff);                        //清除RX FIFO寄存器
                return 1;
        }         
  Set_NRF24L01_CE;
        return 0;//没收到任何数据
}
接收端主函数:
int main(void)
{
         u8 Rx_Buf[32];
           int i=0;
         
        SystemInit();                          //系统时钟初始化为72M          SYSCLK_FREQ_72MHz
        delay_init(72);                             //延时函数初始化          
        NVIC_Configuration();                  //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
        LED_Init();                                //LED端口初始化
          uart_init(9600);                        //串口初始化为9600
        NRF24L01_Init();                        //初始化2401        SPI        IO配置

        while (NRF24L01_Check())                        //检验是读写否运行正常
                printf("2401 wrong!\r\n"),delay_ms(1000);
                printf("2401 is ok!");

        RX_Mode();                                //接收模式                       
        while(1)
                {
                        if(NRF24L01_RxPacket(Rx_Buf))                //判断并且读取数据
                                for(i=0;i<32;i++)                                //打印32个数据Rx_Buf[0]~Rx_Buf[31]
                        AnBT_Uart1_Send_Char(Rx_Buf[i]);                //串口打印数据       
                }
}


现在问题是发送0~99数据总会丢失那么几个数据(<=5个),发送时间间隔为10ms。
网上说WIFI有干扰啊,后我把2.4GHz改为2.5Ghz        问题没能解决
还有说 电源上面要焊接一个滤波电容。我买的成品,应该有焊接过的!

归根到底可能是我的程序配置的不对,望大神们给点拨一下,感觉不尽。

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

 楼主| 发表于 2014-4-26 11:43:33 | 显示全部楼层
问题解决了....
没接收到数据后再手动重发一下就好了,while循环一直到收到数据就好了。
据说丢几个数据包是正常现象,需要手动重发.....

出0入0汤圆

发表于 2014-4-29 15:07:10 | 显示全部楼层
楼主你好,首先恭喜你调试通过,我还在磨练中,我的单片机是飞思卡尔的xd256cal。想请教一个问题,不回答也没关系,哈哈!我的两片nrf24l01,互相收发,正常运行1-2分钟就无法发送(发送溢出中断)了。我的通讯过程是A机发送B机接收。具体是:A机每一个循环周期发送一次,发送完成后产生中断,我切换成接收模式。接收完了读取数据然后返回主程序,当然中断标志及缓存区都清除的。B机:B机初始化就是接收模式,接收到数据后中断接收完了读取数据清除中断标志及缓存区。然后切换成发送模式。发送完成后清除中断,然后再切换成接收模式等待数据到来,开始下一个轮回。貌似这样应该没有问题啊,怎么工做一会就不行了呢?请指教一下,谢谢!

出0入0汤圆

 楼主| 发表于 2014-5-1 23:21:22 | 显示全部楼层
jiang887786 发表于 2014-4-29 15:07
楼主你好,首先恭喜你调试通过,我还在磨练中,我的单片机是飞思卡尔的xd256cal。想请教一个问题,不回答也 ...

你传送的数据量不大吧!1~2分钟后出现通信失败感觉算是好的了..........
个人看法:24L01数据丢失,有时发送到最大次数后仍没有收到应答,属于正常现象。当这种情况发生后如要保证数据的完整性就需要手动重发。重新发送上次未成功发送的数据,while循环直到发送成功return 0。
我感觉你那就是出现了一次“正常”的丢包现象后,程序逻辑死掉了......A端发送成功后变为接收模式等待数据接收,此时B端收到数据后改为发送模式但是发送完数据后没有收到应答(此时就需要手动重发)后自动转入接收模式。在这里A和B都进入接收模式,所以程序逻辑死在这里了。
当然这只是我根据自己的经验猜想的。你可以尝试用串口调试一下,比如返回(验证)一些猜想的错误。
2401也没有搞太深入,现在只是实现了自己需要的功能......希望能帮到你,还望大家一起交流学习进步!!!

出0入0汤圆

 楼主| 发表于 2014-5-1 23:22:29 | 显示全部楼层
jiang887786 发表于 2014-4-29 15:07
楼主你好,首先恭喜你调试通过,我还在磨练中,我的单片机是飞思卡尔的xd256cal。想请教一个问题,不回答也 ...

飞思卡尔......你是用来做智能车吧......用2401实现上下通讯???

出0入0汤圆

发表于 2014-5-3 20:39:15 | 显示全部楼层
生来孤独 发表于 2014-5-1 23:22
飞思卡尔......你是用来做智能车吧......用2401实现上下通讯???

哈哈,是的,我根据你的思路再试试,谢谢指教。这个通讯搞好了,我试试搞搞两轮直立车,

出0入0汤圆

发表于 2014-11-25 21:52:18 | 显示全部楼层

出0入0汤圆

发表于 2015-1-25 13:09:25 | 显示全部楼层
我的问题的是每个包32字节,发6000以下的不会丢失也不会乱码,发10000个包只能收到9200左右,并且中间有部分乱码的,搞了很久都没找到什么原因。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-25 22:11

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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