大手子们,请问一下,我用的一对NRF24L01进行一对一通信,不过一个是自己设计的芯片加外围电路,能接收和发送成功,状态寄存器(sta)能显示0x2e和0x3e,另一个是市面上买的NRF24L01模块,能发送但是不能接收,状态寄存器没有出现0x3e,只出现过两次能接收的情况,相对于不能接收的情况只能说是寥寥无几。
我两个NRF24L01的收发逻辑都是依靠IRQ中断服务函数来切换的,这两个NRF都能发送,应该不是程序问题吧?是硬件电源电压的问题吗?模块我也加了10uF电容,同时也在他要安装的电路板上也加了两个10uF以上的电容,是不是滤波不彻底呀,还是其他的原因。以下是几个主要函数和配置:
/*配置*/
CE_LOW; //拉低CE,注意:读/写nRF寄存器均需要将CE拉低,使其进入待机或者掉电模式才可以
//初始化SI24R1
SPI_Write_Byte(WRITE_REG_CMD + SETUP_AW, 0x03); //配置通信地址的长度,默认值时0x03,即地址长度为5字节
SPI_Write_Byte(FLUSH_RX,0xff); //清除RX FIFO寄存器
SPI_Write_Buf(WRITE_REG_CMD + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);
SPI_Write_Buf(WRITE_REG_CMD + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); //与发送端的发送目标地址一致
SPI_Write_Byte(WRITE_REG_CMD + SETUP_RETR, 0x1a); //自动重发延迟为500+86us,重发次数10次
SPI_Write_Byte(WRITE_REG_CMD + EN_AA, 0x01); //接收数据后,只允许频道0自动应答
SPI_Write_Byte(WRITE_REG_CMD + EN_RXADDR, 0x01); //只允许频道0接收数据
SPI_Write_Byte(WRITE_REG_CMD + RF_SETUP, 0x27); //设置发射速率为2MHZ,发射功率为最大值0dB
SPI_Write_Byte(WRITE_REG_CMD + RF_CH, 40); //设置通道通信频率,工作通道频率可由以下公式计算得出:Fo=(2400+RF_CH)MHz.并且射频收发器工作的频率范围从2.400-2.525GHz
SPI_Write_Byte(WRITE_REG_CMD + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为5字节,只有接收的数据达到此长度时,才会触发RX_DS中断
SPI_Write_Byte(WRITE_REG_CMD + CONFIG, 0x0f); //默认处于接收模式
SPI_Write_Byte(WRITE_REG_CMD + STATUS, 0xff); // 清除所有的中断标志位
CE_HIGH;
void SI24R1_SendPacket(u8* tfbuf)
{
CE_LOW; //拉低CE,进入待机模式,准备开始往SI24R1中的寄存器中写入数据
// SPI_Write_Buf(WRITE_REG_CMD + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); //装载接收端地址,由于这里只有一个通道通讯,不用改变接收端的SI24R1的接收通道地址,所以,这句可以注释掉
SPI_Write_Buf(WR_TX_PLOAD, tfbuf, TX_PLOAD_WIDTH); //将数据写入TX端的FIFO中,写入的个数与TX_PLOAD_WIDTH设置值相同
SPI_Write_Byte(WRITE_REG_CMD + CONFIG, 0x0e); //将SI24R1配置成发射模式
SPI_Write_Byte(WRITE_REG_CMD + STATUS, 0x7e); //写0111 xxxx 给STATUS,清除所有中断标志,防止一进入发射模式就触发中断
CE_HIGH; //拉高CE,准备发射TX端FIFO中的数据
delay_us(200); //CE拉高后,需要延迟至少130us
}
void EXTI1_IRQHandler(void)/*NRF24L01中断处理函数*/
{
if (EXTI_GetITStatus(EXTI_Line1)!=RESET)
{
sta = SPI_Read_Byte(READ_REG_CMD+STATUS); // 读取状态寄存其来判断数据接收状况
printf("statuas:%x\r\n",sta);
if(sta & 0x40)//bit6:数据接收中断
{
FLY_Connect_OK = 1; //飞机与遥控器已连接
SI24R1_ReceivePacket(RxBuf); //将数据从RX端的FIFO中读取出来
FLYDataRx_OK = 1;
SPI_Write_Byte(WRITE_REG_CMD+STATUS,RX_DR); //清除RX_DR中断
}
else if((sta&0x10)>0)//达到最大发送次数中断
{
LED_Off(LED1); //LED1灭时,表示和飞机通讯中断
RX_Mode(); //将SI24R1的模式改为接收模式,等待接收数据
SPI_Write_Byte(WRITE_REG_CMD+STATUS,MAX_RT); //清除MAX_RT中断
SPI_Write_Byte(FLUSH_TX,0xff);
}
else if((sta&0x20)>0)//TX发送完成中断
{
RX_Mode(); //将SI24R1的模式改为接收模式,等待接收数据
if(Fly_Lock == 0x01)
{
LED_On(LED1); //LED1常亮表示飞机已经解锁成功,并正在进行数据通讯
}else
{
LED_Toggle(LED1); //LED1闪烁表示飞机加锁模式中,但是和飞机通讯成功
}
SPI_Write_Byte(WRITE_REG_CMD+STATUS,TX_DS); //清除TX_DS中断
SPI_Write_Byte(FLUSH_TX,0xff); //清空TX_FIFO
}
EXTI_ClearITPendingBit(EXTI_Line1); //清除标志
}
}
void RX_Mode(void)/*接收模式*/
{
CE_LOW; //拉低CE,进入待机模式,准备开始往SI24R1中的寄存器中写入数据
SPI_Write_Byte(WRITE_REG_CMD + CONFIG, 0x0f); //配置为接收模式
SPI_Write_Byte(WRITE_REG_CMD + STATUS, 0x7e); //写0111 xxxx 给STATUS,清除所有中断标志,防止一进入接收模式就触发中断
CE_HIGH; //拉高CE,准备接受从外部发送过来的数据
delay_us(100);
}
void SI24R1_SendPacket(u8* tfbuf)/*发送数据包*/
{
CE_LOW; //拉低CE,进入待机模式,准备开始往SI24R1中的寄存器中写入数据
SPI_Write_Buf(WRITE_REG_CMD + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); //装载接收端地址,由于这里只有一个通道通讯,不用改变接收端的SI24R1的接收通道地址,所以,这句可以注释掉
SPI_Write_Buf(WR_TX_PLOAD, tfbuf, TX_PLOAD_WIDTH); //将数据写入TX端的FIFO中,写入的个数与TX_PLOAD_WIDTH设置值相同
SPI_Write_Byte(WRITE_REG_CMD + CONFIG, 0x0e); //将SI24R1配置成发射模式
SPI_Write_Byte(WRITE_REG_CMD + STATUS, 0x7e); //写0111 xxxx 给STATUS,清除所有中断标志,防止一进入发射模式就触发中断
CE_HIGH; //拉高CE,准备发射TX端FIFO中的数据
delay_us(150); //CE拉高后,需要延迟至少130us
}