打印
[51单片机]

NRF24L01求助

[复制链接]
1147|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
慢慢学|  楼主 | 2014-10-22 13:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
用NRF24L01实现无线通信的时候,发射端发射出数据后,检测不到TX_DS发送完成中断是怎么回事啊?
以下程序是实现发射端的检测。目的是检测,数据是否发送成功?

问题:不知道是什么原因导致数据发送不成功,没有产生中断标志,不知道怎么改进,希望大神指点!!!

uint8 buffer[5]={0x00,0x00,0x00,0x00,0x00};
void main()
{           
        nrf2401_init();
        NRF_SetRXMode();
        while(1)
        {
                if(KEY_1==0)//有按键按下,则发送
                {       
                        x=1;
                }while(!KEY_1);
                if(x)
                {
                        NRF_Write(buffer1,5);
                        while(NRF_CheckACK());        //发送数据后,检测是否发送完成后,检测不到发送完成TX_DS中断标志。
                        NRF_SetRXMode();x=0;
                }       
        }
}
/**********************************************************************
函数功能:NRF应答信号检测(用于发射)
入口参数:无
返    回:无
备    注:无
**********************************************************************/
uint8 NRF_CheckACK()
{       
        sta=NRFReadReg(R_REGISTER+STATUS);          //读取状态寄存器的值
        if(TX_DS||MAX_RT)                                           //发送完成中断或者发送次数过多失败中断
        {         
                NRFWriteReg(W_REGISTER+STATUS,NRFReadReg(W_REGISTER+STATUS)|0x30); // 清除TX_DS或MAX_RT中断标志
                CSN=0;
            NRFSPI(FLUSH_TX);//用于清空FIFO   
        CSN=1;
            return(0);
        }
        else
        {        P36=~P36;
                return(1);
        }
}
/**********************************************************************
函数功能:NRF设置为接收模式
入口参数:无
返    回:无
备    注:无
**********************************************************************/
void NRF_SetRXMode()
{
        CE_NRF2401=0;
        NRFWriteReg(W_REGISTER+CONFIG,0x0f);//16位CRC校验使能、上电、接受模式 ,IRQ中断收发响应
        CE_NRF2401=1;
        delay(15);//保持10us秒以上        
}
/**********************************************************************
函数功能:SPI初始化(最先设置NRF24L01为接受模式)
入口参数:无
返    回:无
备    注:无
**********************************************************************/
void nrf2401_init()
{
        delay(12);//让系统什么都不干       
        CE_NRF2401=0;//确保nrf2401在待机模式1,(疑问,但是寄存器0x00的PWR_UP复位值为0,为掉电模式,原理上可以不写这条语句)
        CSN=1;           //SPI  disable
        SCK=0;
        IRQ_NRF2401=1;//中断引脚拉高
       
        NRFWriteReg(W_REGISTER+EN_AA,0X00);                                                        //关闭自动应答
        NRFWriteReg(W_REGISTER+EN_RXADDR,0X00);                                                //关闭通道接收
        NRFWriteReg(W_REGISTER+RF_CH,0X00);                                                        //设置射频通道的运行频率 收发频率必须一致

        NRFWriteReg(W_REGISTER+SETUP_RETR,0X00);                                        //禁止自动重发
        NRFWriteReg(W_REGISTER+RF_SETUP,0X07);                                                //2Mbps,发射功率0dB,低噪声放大器
        NRFWriteTxData(W_REGISTER+RX_ADDR_P1,RxAddr,RX_ADDR_WITDH);        //写接收端地址,采用通道1作为模块的接受通道
        NRFWriteReg(W_REGISTER+RX_PW_P1,RX_ADDR_WITDH);                                //接收通道1 数据宽度设置
        CE_NRF2401=1;
        delay(150);//保持10us秒以上
}
/**********************************************************************
函数功能:写数据
入口参数:无
返    回:无
备    注:无
**********************************************************************/
void NRF_Write(uint8* buffer,uint8 length)
{
        //int8 i=0;
        if(length>TX_DATA_WITDH)
                length=TX_DATA_WITDH;
        CE_NRF2401=0;
        NRFWriteTxData(W_REGISTER+TX_ADDR,TxAddr,TX_ADDR_WITDH);//写寄存器指令+发送地址使能指令+发送地址+地址宽度
        NRFWriteTxData(W_REGISTER+RX_ADDR_P0,TxAddr,TX_ADDR_WITDH);//为了应答接收设备,接收通道0地址和发送地址相同
        NRFWriteTxData(W_TX_PAYLOAD,buffer,length);//写入数据
        NRFWriteReg(W_REGISTER+CONFIG,0x0e);      // CRC使能,16位CRC校验,上电   //发送模式
        CE_NRF2401=1;
        delay(5);//保持10us秒以上
}

相关帖子

沙发
慢慢学|  楼主 | 2014-10-22 13:31 | 只看该作者
真心求助,希望大神帮忙!!

使用特权

评论回复
板凳
慢慢学|  楼主 | 2014-10-22 13:45 | 只看该作者
希望做过的高手,分享下经验!谢谢了!!

使用特权

评论回复
地板
ningling_21| | 2014-10-22 14:22 | 只看该作者
只有接收端正确接收,才会在发送端出现发送完成的IRQ中断信号。

使用特权

评论回复
5
慢慢学|  楼主 | 2014-10-22 14:26 | 只看该作者

这3条语句,是实现只检测发送端,不管接收端的!!!

本帖最后由 慢慢学 于 2014-10-22 14:28 编辑
ningling_21 发表于 2014-10-22 14:22
只有接收端正确接收,才会在发送端出现发送完成的IRQ中断信号。

我看见一个帖子,,,
先配置这3条语句:
NRFWriteReg(W_REGISTER+EN_AA,0X00);   //关闭自动应答
NRFWriteReg(W_REGISTER+EN_RXADDR,0X00);  /关闭通道接受
NRFWriteReg(W_REGISTER+RF_CH,0X00);//设置射频通道的运行频率 收发频率必须一致

就可以实现检测是否发送成功,然后我现在就是这样试的,但是还是检测不到TX_DS的中断信号???

使用特权

评论回复
6
ningling_21| | 2014-10-22 16:11 | 只看该作者
慢慢学 发表于 2014-10-22 14:26
我看见一个帖子,,,
先配置这3条语句:
NRFWriteReg(W_REGISTER+EN_AA,0X00);   //关闭自动应答

只有发送端,发送数据后正常情况会产生最大重发的中断IRQ信号输出...

使用特权

评论回复
7
慢慢学|  楼主 | 2014-10-22 16:31 | 只看该作者
ningling_21 发表于 2014-10-22 16:11
只有发送端,发送数据后正常情况会产生最大重发的中断IRQ信号输出...

但是一个中断都没有产生是个什么情况啊!!!
完全不应该啊!我发送一个字符后,转到检测是否有中断,然后就一直检测不到有中断产生!!!

使用特权

评论回复
8
ningling_21| | 2014-10-22 17:48 | 只看该作者
慢慢学 发表于 2014-10-22 16:31
但是一个中断都没有产生是个什么情况啊!!!
完全不应该啊!我发送一个字符后,转到检测是否有中断,然 ...

寄存器可能没正确配置,或硬件有问题

使用特权

评论回复
9
慢慢学|  楼主 | 2014-10-22 19:48 | 只看该作者
ningling_21 发表于 2014-10-22 17:48
寄存器可能没正确配置,或硬件有问题

void nrf2401_init()
{
        delay(12);//让系统什么都不干        
        CE_NRF2401=0;//确保nrf2401在待机模式1,(疑问,但是寄存器0x00的PWR_UP复位值为0,为掉电模式,原理上可以不写这条语句)
        CSN=1;           //SPI  disable
        SCK=0;
        IRQ_NRF2401=1;//中断引脚拉高
        
        NRFWriteReg(W_REGISTER+EN_AA,0X00);                             //关闭自动应答
        NRFWriteReg(W_REGISTER+EN_RXADDR,0X00);                        //关闭通道接收
        NRFWriteReg(W_REGISTER+RF_CH,0X00);                             //设置射频通道的运行频率 收发频率必须一致

        NRFWriteReg(W_REGISTER+SETUP_RETR,0X00);                         //禁止自动重发
        NRFWriteReg(W_REGISTER+RF_SETUP,0X07);                          //2Mbps,发射功率0dB,低噪声放大器
        NRFWriteTxData(W_REGISTER+RX_ADDR_P1,RxAddr,RX_ADDR_WITDH);        //写接收端地址,采用通道1作为模块的接受通道
        NRFWriteReg(W_REGISTER+RX_PW_P1,RX_ADDR_WITDH);                //接收通道1 数据宽度设置
        CE_NRF2401=1;
        delay(150);//保持10us秒以上
}
这是我寄存器的设置!!!你看看有问题吗???

至于你说得硬件的问题,我不是特别清楚你指的是那些方面的?你能说说硬件的那些方面吗?

使用特权

评论回复
10
ningling_21| | 2014-10-22 20:08 | 只看该作者
初始化好像不对
void init_NRF24L01(void)
{
    inerDelay_us(100);

        CE_L();

        CS_H();

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

  SPI_RW_Reg(WRITE_REG + CONFIG,    0x0e);                   //发送模式
//  CE=1;
        CE_H();
  inerDelay_us(10);
  inerDelay_us(10);
//  SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);                   //接收模式
}

使用特权

评论回复
11
慢慢学|  楼主 | 2014-10-23 10:43 | 只看该作者
ningling_21 发表于 2014-10-22 20:08
初始化好像不对

刚刚发现的一个新问题,我在单独调试发送端的时候,我按一个键然后发送一个字符,发送后,检测有没有收到接收中断或者发送次数过多中断,但是就会一直处于检测状态,程序就不继续运行了,这是只要将MOSI和MISO短接一下,程序由自动运行了!!!这是怎么回事啊!!

使用特权

评论回复
12
ningling_21| | 2014-10-23 12:48 | 只看该作者
慢慢学 发表于 2014-10-23 10:43
刚刚发现的一个新问题,我在单独调试发送端的时候,我按一个键然后发送一个字符,发送后,检测有没有收到 ...

还是程序的问题

使用特权

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

本版积分规则

18

主题

140

帖子

2

粉丝