打印

调试NRF24L01遇到的问题

[复制链接]
1151|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
nightingale2003|  楼主 | 2016-11-26 09:07 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 nightingale2003 于 2016-11-26 09:09 编辑

目的:
写了个程序,分为接收端和发送端,发送数据两位
发送端用while,持续发送一个数(A),直到A发送后才进行后续发送BCD
接收端则持续接收。
现象:
现在发现如果先给接收端上电,接收端正常接收,即A-B-C-D
但是如果先给发送端上电,则接收到的变成   (A-A)-A-B-C,
也就是刚上电马上收到两个A,之后的都慢一拍,最后一个数则丢失。
情况1(正常)
发送端                接收端
                上电(接受中)
发A                收到A
发B                收到B
发C                收到C


情况2(有问题)
发送端                接收端
上电(发A)        
----                上电(收到A  A)
发B                收到A
发C                收到B


进行查错发现的线索:
发送端先上电,数据发送不出去,查STATE寄存器为0x0f,也就是TX_FIFO寄存器满
用write_SPI(FLUSH_TX,0);清除TX_FIFO也没法清除FIFO以及标志位。造成的结果就是  
发送端发送的是B,结果接收端接收到的是A;发送端发送C,接收端收到B,以此类推;

为了便于查看,只列出主要函数(用的STC15的单片机,12M频率)
发送函数:
uchar nRF24l01_txpacket(uchar dat1,uchar dat2)                                                        //发送数据包,发送成功返回1     
{
        uchar temp;
        temp=0;
        CE=0;
        FIFO[0]=dat1;
        FIFO[1]=dat2;
        write_SPI(0x20+CONFIG,0x3e);
        write_SPI_buf(W_TX_PAYLORD,FIFO,2);
        CE=1;
        delayms(1);
        do
                state=read_SPI(STATUS);
        while((state&0x30)==0);
        if(TX_DS)
                temp=1;
        else
                temp=0;        
        CE=0;

        write_SPI(0x20+STATUS,0xff);
        rw_SPI(FLUSH_TX);

        return temp;
        
}
接收函数
uchar nRF24l01_rxpacket(uchar *str)
{
        uchar temp=0;
        state=read_SPI(STATUS);
        if(RX_DR)
        {
                CE=0;
                write_SPI(0x20+STATUS,0xff);
                read_SPI_buf(R_RX_PAYLORD,str,2);
                temp=1;
        }
        CE=1;
        return temp;
}

发送端主函数
void main()
{        
        init();
        flag_sc=1;
        TR0=1;        

/*-----------------------------------------找寻匹配接收器阶段-------------------------------------------------------*/                          
        //先取得随机数A         假设0x55

        while(nRF24l01_txpacket(0x20,0x55)!=1)                                   //待修改参数                                                                                                                                           11111111
        {
                if(T0_count>=250)                                                            //超时则完全休眠,等待重启
                        deep_sleep();
                delayms(20);                                       
        }
        TxSend(0x01);
/*-----------------------------------------确认该频道有无载波,没有则发送B作为频道-------------------------------------------------------*/
        do        
        {
                //再取随机数B        假设0x66
                P0_ADDRESS[4]=0x55;                                                                        //待修改参数                                                                                                                                           11111111
                CE=0;
                write_SPI_buf(0x20+TX_ADDR,P0_ADDRESS,5);
                write_SPI_buf(0x20+RX_ADDR_P0,P0_ADDRESS,5);
                write_SPI(0x20+RF_CH,0x66);
                setrx_nRF24l01();
                T0_count=0;
                flag_cd=0;
                delay(10);
                while(T0_count<=40)                                                                        //等待2S  或者检测到载波
                {
                        flag_cd=(bit)read_SPI(CD);
                        if(flag_cd==1)
                                break;
                }
                delay(10);                                                                                        //do while时用?
        }
        while(flag_cd==1);

        TxSend(0x02);
        CE=0;
        write_SPI(0x20+RF_CH,3);                                                           //回原始频率给接收端发信号
        T0_count=0;

        CE=1;
        write_SPI(FLUSH_TX,0);
        nRF24l01_txpacket(0x30,0x66);
        while(nRF24l01_txpacket(0x30,0x66)!=1)                                   //待修改参数                                                                                                                                           11111111
        {
                if(T0_count>=250)                                                           //超时则完全休眠,等待重启
                        deep_sleep();                                
        }
        CE=0;
        write_SPI(0x20+RF_CH,0x66);                                  //待修改参数                                                                                                                                           11111111
        flag_sc=0;                                                                 //匹配完毕
        GREEN=0;                                                                 //绿灯亮
        TR0=0;

        while(1)
        {
                delayms(2000);
                while(nRF24l01_txpacket(0x30,0x77)!=1);                                                                                       
                GREEN=1;
        }
}

接收端的都在中断中处理,TxSend是串口发送的函数(调试用),FIFO数组用来存放发送接收的数据
void NRF_initerrupt() interrupt 0                                         //NRF发送完毕,中断
{
        if(nRF24l01_rxpacket(FIFO))
        {
#ifdef UARTtest
                TxSend(FIFO[1]);                                          
#endif        
                main_count=0;

                if(flag_sc==1)
                {
                        CE=0;
                        if((FIFO[0]&0x10)==0)                   //发送的是地址
                        {
                                P0_ADDRESS[4]=FIFO[1];
                                write_SPI_buf(0x20+TX_ADDR,P0_ADDRESS,5);
                                write_SPI_buf(0x20+RX_ADDR_P0,P0_ADDRESS,5);                        
                        }
                        else                                          //发送的频道
                        {
                                write_SPI(0x20+RF_CH,FIFO[1]);
                                flag_sc=0;
#ifdef UARTtest
                read_SPI_buf(TX_ADDR,FIFO_test,5);
                TxSend(FIFO_test[4]);
                read_SPI_buf(RF_CH,FIFO_test,1);
                TxSend(FIFO_test[0]);                                          
#endif        
                        }                                                                                                                                                                                                                                       
                }
                else                                                   //接收到的是移动数据
                {

                }                                       
                setrx_nRF24l01();      //前面关了CE,需要重新开启
        }        
}

相关帖子

沙发
dirtwillfly| | 2016-11-26 10:27 | 只看该作者
本帖最后由 dirtwillfly 于 2016-11-26 11:02 编辑

mcu把字符发送给NRF24L01,NRF24L01并不是马上发送出去的,有一个延时。
最要定义一个通讯协议,保证数据的完整性

使用特权

评论回复
板凳
皈依| | 2016-11-26 10:40 | 只看该作者
程序和系统问题,通讯是好的 逻辑没处理好 上电初始化也要一段时间的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

31

主题

105

帖子

2

粉丝