实验目的:stm32开发板 + nrf24l01通信,通过两块开发板实现数据互传,并在串口调试助手上打印出来。
????????nrf24l01这个模块用起来并不难,当然这是我调试完了站在上帝视角来说的,如果作为小白来调试,肯定够你喝一壶了。
那么这个模块简单在哪里?难在哪里?
????????简单在例程很多,原子的例程直接改一改就可以直接用,难的在于并不是所有人都拥有好运,下完别人的程序就好用,最重要的一点是一个发射端、一个接收端,无法通信的时候到底是发射端出了问题还是接收端出了问题?这些都是让你头大的地方。
下面我来讲一下如何去解决如何判断发射端还是接收端出了问题。
????????首先我们来看一下nrf24l01的寄存器,我们需要关注两个寄存器一个是status一个是fifo_status,发射端status寄存器正常的输出值是2e,fifo_status寄存器正常的输出值是11,这里我们需要用printf函数打印出来,后面我将贴上程序;接收端只需要看status寄存器即可,status的输出值为40。能输出正常值的前提是发射端和接收端都得接上,得通电,不能就弄个发射端在那调,肯定不会出现逾期的现象,如果不接接收端来调试发射端,输出的结果是status:1e,fifo_status:1。到时候你肯定就懵逼了。叫天不应,叫地不灵。不用怕,下面我们来看如何加printf函数打印出寄存器的数据。
这个是发送端的数据,我们只需在TxPacket函数里将status和fifo_status的值打印出来即可。
u8 NRF24L01_TxPacket(u8 *txbuf)
{
u8 sta,fifo_sta;
SPI1_SetSpeed(SPI_BaudRatePrescaler_8);//spi速度为9Mhz(24L01的最大SPI时钟为10Mhz)
NRF24L01_CE=0;
NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);//写数据到TX BUF 32个字节
NRF24L01_CE=1;//启动发送
while(NRF24L01_IRQ!=0);//等待发送完成
sta=NRF24L01_Read_Reg(STATUS); //读取状态寄存器的值
fifo_sta = NRF24L01_Read_Reg(NRF_FIFO_STATUS);
printf("send status is %x \r\n",sta);
printf("send fifo_status is %x \r\n",fifo_sta);
NRF24L01_Write_Reg(NRF_WRITE_REG+STATUS,sta); //清除TX_DS或MAX_RT中断标志
if(sta&MAX_TX)//达到最大重发次数
{
NRF24L01_Write_Reg(FLUSH_TX,0xff);//清除TX FIFO寄存器
return MAX_TX;
}
if(sta&TX_OK)//发送完成
{
return TX_OK;
}
return 0xff;//其他原因发送失败
}
接收端需要打印的代码,将sta的值printf出来就可以了。
u8 NRF24L01_RxPacket(u8 *rxbuf)
{
u8 sta;
SPI1_SetSpeed(SPI_BaudRatePrescaler_8); //spi速度为9Mhz(24L01的最大SPI时钟为10Mhz)
sta=NRF24L01_Read_Reg(STATUS); //读取状态寄存器的值
printf("send status is %x \r\n",sta);
NRF24L01_Write_Reg(NRF_WRITE_REG+STATUS,sta); //清除TX_DS或MAX_RT中断标志
if(sta&RX_OK)//接收到数据
{
NRF24L01_Read_Buf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据
NRF24L01_Write_Reg(FLUSH_RX,0xff);//清除RX FIFO寄存器
return 0;
}
return 1;//没收到任何数据
}
????????通过以上的手段,我们就可以判断出是接受端出了问题还是发射端出了问题。从而解决了别人的程序拿过来用不了,又不会调试的尴尬局面,又解决了如何去判断发射端还是接收端出问题,真是一箭十三雕啊,哈哈。
下面是寄存器,大家可以对照寄存器来看一下你的程序打印出了什么代码。
如果你是在调不出来不妨来看看我的代码,能让你也直接站在上帝视角。
这是我用的开发板。如果用杜邦线的话,可能会因为杜邦线接触不好也会造成通信的不流畅。
|