OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4739|回复: 5

NRF24L01发送方每发送4个字节接收方只接收到一两个,然后发送失败要接收方MCU复位

[复制链接]

2

主题

13

帖子

0

精华

新手上路

积分
41
金钱
41
注册时间
2015-11-13
在线时间
0 小时
发表于 2015-11-22 14:04:26 | 显示全部楼层 |阅读模式
5金钱
收发都设置了每次发送一个字节,都开启了自动应答。看着发送端发送第一个字符,第二个字符,第三个字符,第四个字符逐个显示出来了,然后就显示发送失败了。而接收方只收到一两个字符(在串口显示出来)。但是如果接收方MCU复位,则可以继续收发,发出去的是新的四个,而“收到”(准确来说是通过串口显示出来的)却是上一次发送的第二个字符。接收方的MCU是C51<br />
<br />
<div   style="background-color:#E8E8E8;">
[mw_shl_code=c,true]// 接收方的接收函数
uchar nRF24L01_RxPacket(unsigned char* rx_buf)
{
    uchar flag=0;
    uchar status;
       
        status=SPI_RD_Reg(NRFRegSTATUS);        // 读取状态寄存其来判断数据接收状况
        if(status &amp; 0x40)                                // 判断是否接收到数据
        {
                CE = 0;
                SPI_Read_Buf(RD_RX_PLOAD,rx_buf,RX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer
                SPI_WR_Reg(FLUSH_RX,0xff);//清除RX FIFO寄存器
                flag =1;                        //读取数据完成标志
        }

        SPI_WR_Reg(WRITE_REG+NRFRegSTATUS, status);   //接收到数据后RX_DR,TX_DS,MAX_RT都置高为1,通过写1来清除中断标志
        CE = 1;
        return flag;
}


[/mw_shl_code]
[mw_shl_code=c,true][/mw_shl_code]
[mw_shl_code=c,true]// 接收方NRF初始化函数[/mw_shl_code]
[mw_shl_code=c,true]void init_NRF24L01(void)
{
&nbsp; &nbsp;uchar buf[5]={0};
&nbsp; &nbsp;Delay_n10us(10);
&nbsp; &nbsp;CE = 0; &nbsp; &nbsp;// chip enable
&nbsp; &nbsp;CSN= 0; &nbsp; &nbsp;// Spi disable&nbsp;
&nbsp;&nbsp;[/mw_shl_code]
[mw_shl_code=c,true]   // 这一句似乎没什么用~~~~~
&nbsp; SPI_Read_Buf(TX_ADDR, buf, TX_ADR_WIDTH);//debug 测试原来的本地地址:复位值是:0xE7 0xE7 0xE7 0xE7 0xE7
[/mw_shl_code]
[mw_shl_code=c,true]}[/mw_shl_code]
[mw_shl_code=c,true]
[/mw_shl_code]
[mw_shl_code=c,true]
[/mw_shl_code]
[mw_shl_code=c,true] // 接收方main函数
void main()
{
        uchar Tx_Buf;        //发送的信息1
        uchar Rx_Buf;          //接收到的数据暂存
        Uart_init();
        init_NRF24L01();

        LED_NRFLink=0;

        //检查不到24l01则报警
        while(NRF24L01_Check())               
        {
                LED_NRFLink=0;
                delayms(500);
                LED_NRFLink=1;
                delayms(500);
        }

        LED_NRFLink=1;

        while(1)
        {       
                RX_Mode();//接收模式
                while(!nRF24L01_RxPacket(&amp;Rx_Buf)); //等待接收数据 ,返回1则接收到数据 ,在等待接收数据期间,可以随时变成发送模式  

                // 通过串口发送数据
                SBUF=Rx_Buf;
                while(!TI);
        }
}[/mw_shl_code]
</div>
发送方是原子哥的代码,只将TX_PLOAD_WIDTH从32改成了1。<br />
请问这是什么问题?<br />

最佳答案

查看完整内容[请看2#楼]

 发现原因了。首先要再描述一下我的问题:大概每发送4个,接收方只能收到一个或两个,之后发送端就显示失败了。如果复位MCU,则又可以收到,但是收到的是之前发送的四个的后面内容,当然,这时候发送方又发出了新的四个。 问题来了: ①发送方发送了四个,发送成功了吗?答:成功了,因为复位MCU可以收到前面的数据 ②接收方收到了多少?答:3个!!!如果小于3个,那么发送方在发送第三个的时候就会失败,不会显示4个字 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

13

帖子

0

精华

新手上路

积分
41
金钱
41
注册时间
2015-11-13
在线时间
0 小时
 楼主| 发表于 2015-11-22 14:04:27 | 显示全部楼层
&nbsp;发现原因了。首先要再描述一下我的问题:大概每发送4个,接收方只能收到一个或两个,之后发送端就显示失败了。如果复位MCU,则又可以收到,但是收到的是之前发送的四个的后面内容,当然,这时候发送方又发出了新的四个。<br />
<br />
问题来了:<br />
①发送方发送了四个,发送成功了吗?答:成功了,因为复位MCU可以收到前面的数据<br />
②接收方收到了多少?答:3个!!!如果小于3个,那么发送方在发送第三个的时候就会失败,不会显示4个字符。<br />
③为什么是复位MCU?猜测:程序跑飞了,或者卡住了。答:卡住了。<br />
<br />
看上面的代码是串口发送回PC的,我的串口设置了中断服务函数:<br />
<div   style="background-color:#E8E8E8;">
[mw_shl_code=c,true]// 串口接收
void interrupt_uart() interrupt 4 //串口中断优先等级为4
{
        if(TI) TI=0; // 发送完成,清除该标志位
       
        if(RI)
        {
                RI=0;                                 // 先把接收标志位清零
                Command=SBUF; // 将收到的指令
                GCFlag=1;                        // 收到指令
        }
}
[/mw_shl_code]
</div>
其中的<span style="line-height:1.5;">if(TI) TI=0; 在发送完成遇到TI置高时清零TI。而main函数中又有这样的代码:<br />
<div   style="background-color:#E8E8E8;">
[mw_shl_code=c,true]        while(1)
        {       
               
                while(!nRF24L01_RxPacket(&amp;Rx_Buf)); //等待接收数据 ,返回1则接收到数据 ,在等待接收数据期间,可以随时变成发送模式  

                // 通过串口发送数据
                SBUF=Rx_Buf;
                //while(!TI);  // 死于此
        }
[/mw_shl_code]
</div>
while(!TI)还在等待TI置高。这就是为什么显示出来的字符数是一个或两个或……3,4都有可能。但是就是无法连续接收。这就是因为……人品!!有些时候中断吧TI清0的早,就显示一个,清0得晚就多几个。毕竟中断发生的时机虽然说都是在发送完成之后,但是实际上在发送完成的这个时刻main出于什么状态是不确定的。有些时候中断发生的是瞬间while已经发现了TI为高就过去了,有些时候中断发生while还没执行到判断就被中断打断了,之后中断清0了TI,while永远都出不来了。<br />
<br />
虽然我之前也试过注释掉这个while,但也失败了,可以说是很多错误的集合吧。下面发出可用的RX_Mode函数和RxPacket函数,都是在C51下的代码。实际上这些代码也参照了原子哥的STM32的相关代码,看了他的接收模式配置和接收数据的流程。<br />
<div   style="background-color:#E8E8E8;">
[mw_shl_code=c,true]void RX_Mode(void)
{
    uchar buf[5]={0};
        CE = 0;

        SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址
       
        SPI_WR_Reg(WRITE_REG + EN_AA, 01);     //  频道0自动        ACK应答允许       
        SPI_WR_Reg(WRITE_REG + EN_RXADDR,0x01);  //  允许接收地址只有频道0,如果需要多频道可以参考Page21
        SPI_WR_Reg(WRITE_REG + RF_CH, 40);        //   设置信道工作为2.4GHZ,收发必须一致
        SPI_WR_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
        SPI_WR_Reg(WRITE_REG + RF_SETUP, 0x0F);                   //设置发射速率为2MHZ,发射功率为最大值0dB
       
        SPI_WR_Reg(WRITE_REG + CONFIG, 0x0F);//0x0F);       
        CE = 1;
        Delay_n10us(20); //200us
}

//******************************************************************************************************/
//*函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
//*功能:数据读取后放如rx_buf接收缓冲区中
//******************************************************************************************************/
uchar nRF24L01_RxPacket(unsigned char* rx_buf)
{
    uchar flag=0;
    uchar status;
       
        status=SPI_RD_Reg(NRFRegSTATUS);        // 读取状态寄存其来判断数据接收状况
        SPI_WR_Reg(WRITE_REG+NRFRegSTATUS, status);   //接收到数据后RX_DR,TX_DS,MAX_RT都置高为1,通过写1来清除中断标志
       
        if(status &amp; RX_OK)                                // 判断是否接收到数据
        {
                SPI_Read_Buf(RD_RX_PLOAD,rx_buf,RX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer
                delayms(10);
                SPI_WR_Reg(FLUSH_RX,0xff);//清除RX FIFO寄存器
                flag =1;                        //读取数据完成标志
        }
        return flag;
}[/mw_shl_code]
</div>
以后会来发完整代码的。谢谢大家<br />
<br />
</span><br />
<br />
<br />
回复

使用道具 举报

2

主题

13

帖子

0

精华

新手上路

积分
41
金钱
41
注册时间
2015-11-13
在线时间
0 小时
 楼主| 发表于 2015-11-22 14:05:03 | 显示全部楼层
有一些注释不匹配,不要在意这个细节~
回复

使用道具 举报

557

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165060
金钱
165060
注册时间
2010-12-1
在线时间
2103 小时
发表于 2015-11-22 22:25:36 | 显示全部楼层
帮顶。。。。。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

2

主题

13

帖子

0

精华

新手上路

积分
41
金钱
41
注册时间
2015-11-13
在线时间
0 小时
 楼主| 发表于 2015-11-23 10:16:00 | 显示全部楼层
回复【3楼】正点原子:
<br>---------------------------------
<br>我晕……,好吧,帮顶也是帮忙,谢谢了
回复

使用道具 举报

557

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165060
金钱
165060
注册时间
2010-12-1
在线时间
2103 小时
发表于 2015-11-23 22:39:48 | 显示全部楼层
回复【5楼】几罗星人:
<br>---------------------------------
<br>谢谢分享.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-7-2 17:40

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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