NRF24l01的多对一通信

元气小坏坏 提交于 2019-11-30 02:51:38

前言

怎么说呢,今天又看了一天的nrf,很多东西看起来特别简单,但实际用起来,你会发现漏洞百出。根本不知从何下手。下来就分享一下我的经验。对你应该会有所帮助。以下是基于stm32实现的nrf无线通信。

必看

这篇博客不适合无基础的人来看,因为下面程序我只给出部分程序,所以没基础你可能看不懂程序配置的是什么。我主要分享的是多对一通信时不同通道寄存器的参数如何求取

NRF一对一通信

首先NRF一对一通信没得说很简单,而且出问题的几率很小。一对一通信我就不多讲了,给出主要配置收发的程序。

例(1)一对一通信,发送模式的主要配置

如果单做一对一通信建议就用通道p0吧。

//设置发送地址
const u8 TX_ADDRESS[TX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //地址可以随便修改(仅针对通道P0的地址)
const u8 RX_ADDRESS[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};//接收地址
/*******************************************************************/
//配置发送模式
void NRF24L01_TX_Mode(void)
{               
 NRF24L01_CE=0;     
   NRF24L01_Write_Buf(NRF_WRITE_REG+TX_ADDR,(u8*)TX_ADDRESS,TX_ADR_WIDTH);//写TX节点地址
   NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH); //设置接收节点的地址
   NRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x01);     //0x01使能通道0自动应答
   NRF24L01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01); //使能通道0地址
   NRF24L01_Write_Reg(NRF_WRITE_REG+SETUP_RETR,0x1a);//设置自动重发时间500us+86us,自动重发次数10次
   NRF24L01_Write_Reg(NRF_WRITE_REG+RF_CH,40);     //设置通信频率
   NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f);  //发射参数0db,2Mbps
   NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG,0x0e);    //配置基本工作模式
 NRF24L01_CE=1;//CE为高
}
/********************************************************************/
//发送一次数据
u8 NRF24L01_TxPacket(u8 *txbuf)
{
 u8 sta;
  SPI2_SetSpeed(SPI_BaudRatePrescaler_4);// spi速度
 NRF24L01_CE=0;
   NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);//写数据
  NRF24L01_CE=1;//启动发送
 while(NRF24L01_IRQ!=0);//等待发送完成
 sta=NRF24L01_Read_Reg(STATUS);  //读取寄存器状态值
 NRF24L01_Write_Reg(NRF_WRITE_REG+STATUS,sta); //清楚TX-DS中断标志
 if(sta&MAX_TX)//达到最大重发次数
 {
  NRF24L01_Write_Reg(FLUSH_TX,0xff);//清楚TX-FIFO
  return MAX_TX; 
 }
 if(sta&TX_OK)//发送完成
 {
  return TX_OK;
 }
 return 0xff;//发送失败
}

例(2)一对一接收主要配置


//设置接收地址
const u8 TX_ADDRESS[TX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //地址可以随便修改(仅针对通道P0的地址)
const u8 RX_ADDRESS[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};//接收地址
/************************************************************/
//配置接受模式
void NRF24L01_RX_Mode(void)
//接收程序注释和发送程序注释基本一样
{
 NRF24L01_CE=0;   
   NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH);//配置接收地址
   NRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x01);   //使能通道0自动应答
   NRF24L01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01);  //使能通道0地址
   NRF24L01_Write_Reg(NRF_WRITE_REG+RF_CH,40);     //通信频率
   NRF24L01_Write_Reg(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//P0为通道0接收
   NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f); 
   NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG, 0x0f);//
   NRF24L01_CE = 1; //
}     
/***************************************************************/
//接收程序
u8 NRF24L01_RxPacket(u8 *rxbuf)
{
 u8 sta;                
 SPI2_SetSpeed(SPI_BaudRatePrescaler_8); 
 sta=NRF24L01_Read_Reg(STATUS);  //    
 NRF24L01_Write_Reg(NRF_WRITE_REG+STATUS,sta); //
 if(sta&RX_OK)//
 {
  NRF24L01_Read_Buf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//将接收到的数据传入参数rxbuf中
  NRF24L01_Write_Reg(FLUSH_RX,0xff);//
  return 0; 
 }    
 return 1;//
}  

NRF多对一通信

首先地址的配置要注意,通道P0随意但P1-P5就要注意,给一张图,规律自己找。

在这里插入图片描述
多对一接收配置
在这里插入图片描述在我初步接触时我也很不了解为什么0x01是使能通道0,0X02是使能通道1而0X03却是使能通道1和0,而不是通道2。手册告诉我们这个参数一共有8位其中后6位设制通道。1有效,0无效。接下来我就图解解释吧。

在这里插入图片描述
再来看看接收程序,因为翻了好多博客,大多只给出了多对一的接收配置程序,而没给出如何接收并判断不同通道的数据。
在这里插入图片描述
很多人看到这就产生了疑问,为什么0X00是通道0而0X02是通道1?我继续给大家图解状态寄存器,官方给出,第0位默认为0,1到3位是代表通道号
在这里插入图片描述
所以将sta值与0X0e相与是为了求出通道号,然后用switch语句判断此刻接收的是那个通道的值,然后付给相应的参数。
至于发送程序,配置和一对一发送程序配置一样。只要发送地址和相应通道的接收地址一样即可。

总结

因为之前看了好多博客,对这方面的值是怎么来的都没提及,今天还是看技术手册才明白,虽然STM32的开发大多都是Copy,但我们还是要看懂程序,万一出错,也有个经验。知道大概错那了。

遇到的问题

我不知道是我配置的问题还是nrf的问题,在我配置完之后从机B用通道0单独与主机A
通信正常,从机C用通道1和主机A通信正常,但从机C和从机B同时与主机通信,主机数据接收速度变慢,而且偶尔会出错。不知道是不是我忘记配置什么了还是手上的NRF有问题。分开单独测试都没问题,但一起测试就出问题。你们是否在多对一通信时遇到这种问题(通信变慢或者出错),或者有更好的解决方法评论区请告诉我。谢谢。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!