NRF24L01 一对三通信

注意:NRF24L01 无论是一对一通信,还是一对多通信,其实本质上同一时刻是一对一通信,它是属于半双工通信。你只需要先调通一对一的通信,无论是一对2,一对六也是同一个原理。(基础SPI知识和NRF24L01基础知识不多说)

一、项目背景

1.1项目材料

4块STM32F103C8T6的自制板子,4块NRF24L01无线通信模块。

1.2项目功能

一台主机单片机,进行对三个从机单片机进行监听接收,与三台从机进行交互。(也就是说主机只接收,从机只发送。具体想丰富交互可以自行拓展)

二、主机主要配置代码

2.1主机主要配置代码地址

const u8 TX_ADDRESS0[TX_ADR_WIDTH] = {0x00,0xff,0xff,0xff,0xff}; 
const u8 TX_ADDRESS1[TX_ADR_WIDTH] = {0x01,0xfe,0xaa,0xaa,0xaa}; 
const u8 TX_ADDRESS2[TX_ADR_WIDTH] = {0x02};

const u8 RX_ADDRESS0[RX_ADR_WIDTH] = {0x00,0xff,0xff,0xff,0xff}; 
const u8 RX_ADDRESS1[RX_ADR_WIDTH] = {0x01,0xfe,0xaa,0xaa,0xaa}; 
const u8 RX_ADDRESS2[RX_ADR_WIDTH] = {0x02};

这里一定要注意一下,通道2到通道5,这里配置只需要一个字节的地址。

2.2主机主要接收代码

 void NRF_RX_Mode_BC(void)
 {
 	NRF_CE_LOW();
 	SPI_NRF_WriteBuf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS0,RX_ADR_WIDTH);        //写RX节点地址  
	SPI_NRF_WriteBuf(NRF_WRITE_REG+RX_ADDR_P1,(u8*)RX_ADDRESS1,RX_ADR_WIDTH);        //写RX节点地址  
	SPI_NRF_WriteBuf(NRF_WRITE_REG+RX_ADDR_P1,(u8*)RX_ADDRESS1,1);            //写RX节点地址  
	SPI_NRF_WriteBuf(NRF_WRITE_REG+RX_ADDR_P2,(u8*)RX_ADDRESS2,1);            //写RX节点地址  
	 
 	SPI_NRF_WriteReg(NRF_WRITE_REG+EN_AA,0x3f);                                 //使能通道0的自动应答
 	SPI_NRF_WriteReg(NRF_WRITE_REG+EN_RXADDR,0x3f);                             //使能通道0的接收地址
    
    SPI_NRF_WriteReg(NRF_WRITE_REG+RF_CH,40);                            //设置RF通信频率
    
 	SPI_NRF_WriteReg(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);                    //选择通道0的有效数据宽
	SPI_NRF_WriteReg(NRF_WRITE_REG+RX_PW_P1,RX_PLOAD_WIDTH);                    //选择通道1的有效数据宽
	SPI_NRF_WriteReg(NRF_WRITE_REG+RX_PW_P2,RX_PLOAD_WIDTH);                    //选择通道2的有效数据宽

 	SPI_NRF_WriteReg(NRF_WRITE_REG+RF_SETUP,0x0f);                              //设置TX发射参数,0db增益,2Mbps,低噪声增益开启
 	SPI_NRF_WriteReg(NRF_WRITE_REG+CONFIG, 0x0f);                               //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式
 	NRF_CE_HIGH();                                                              /*CE拉高,进入接收模式*/
     __nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();              
 }

主机设置好接收代码,一通道地址需要重写。重写的时候只写入一通道低字节数据,然后2、3、4、5通道也只写入低字节就可以了,因为2、3、4、5通道地址是共用一通道的后四个高字节地址的。

三、从机主要配置代码

3.1从机主要配置代码地址

const u8 TX_ADDRESS0[TX_ADR_WIDTH] = {0x00,0xff,0xff,0xff,0xff}; 
const u8 TX_ADDRESS1[TX_ADR_WIDTH] = {0x01,0xfe,0xaa,0xaa,0xaa}; 
const u8 TX_ADDRESS2[TX_ADR_WIDTH] = {0x02,0xfe,0xaa,0xaa,0xaa};

const u8 RX_ADDRESS0[RX_ADR_WIDTH] = {0x00,0xff,0xff,0xff,0xff}; 
const u8 RX_ADDRESS1[RX_ADR_WIDTH] = {0x01,0xfe,0xaa,0xaa,0xaa}; 
const u8 RX_ADDRESS2[RX_ADR_WIDTH] = {0x02,0xfe,0xaa,0xaa,0xaa};

从机通道2到通道5,这里代码需要为满5个字节!!!,不能跟主机一样。(自己好好对比一下)

3.2从机主要发送代码

3.2.1 从机1发送代码

 void NRF_TX_Mode_BC(void)
 {
     NRF_CE_LOW();
 	SPI_NRF_WriteBuf(NRF_WRITE_REG+TX_ADDR,TX_ADDRESS0,TX_ADR_WIDTH);    //写TX节点地址 
 	SPI_NRF_WriteBuf(NRF_WRITE_REG+RX_ADDR_P0,RX_ADDRESS0,RX_ADR_WIDTH); //设置TX节点地址,主要为了使能ACK 
 	SPI_NRF_WriteReg(NRF_WRITE_REG+EN_AA,0x3f);     					//使能通道0的自动应答     
 	SPI_NRF_WriteReg(NRF_WRITE_REG+EN_RXADDR,0x3f); 					//使能通道0的接收地址  
 	SPI_NRF_WriteReg(NRF_WRITE_REG+SETUP_RETR,0x1a);					//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次
 	SPI_NRF_WriteReg(NRF_WRITE_REG+RF_CH,40);       				//设置RF通道为CHANAL
 	SPI_NRF_WriteReg(NRF_WRITE_REG+RF_SETUP,0x0f);  					//设置TX发射参数,0db增益,2Mbps,低噪声增益开启 
 	SPI_NRF_WriteReg(NRF_WRITE_REG+CONFIG,0x0e);    					//配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,发射模式,开启所有中断
 	NRF_CE_HIGH();                                                      /*CE拉高,进入发送模式*/
 //    delay_ms(1);                                                        //3 Delay(0x5555); //CE要拉高一段时间才进入发送模式
 	__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();               
 }

从机1配置的是通道0的地址代码!!!

3.2.2 从机2发送代码

 void NRF_TX_Mode_BC(void)
 {
     NRF_CE_LOW();
 	SPI_NRF_WriteBuf(NRF_WRITE_REG+TX_ADDR,TX_ADDRESS1,TX_ADR_WIDTH);    //写TX节点地址 
 	SPI_NRF_WriteBuf(NRF_WRITE_REG+RX_ADDR_P0,RX_ADDRESS1,RX_ADR_WIDTH); //设置TX节点地址,主要为了使能ACK 
 	SPI_NRF_WriteReg(NRF_WRITE_REG+EN_AA,0x3f);     					//使能通道0的自动应答     
 	SPI_NRF_WriteReg(NRF_WRITE_REG+EN_RXADDR,0x3f); 					//使能通道0的接收地址  
 	SPI_NRF_WriteReg(NRF_WRITE_REG+SETUP_RETR,0x1a);					//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次
 	SPI_NRF_WriteReg(NRF_WRITE_REG+RF_CH,40);       				//设置RF通道为CHANAL
 	SPI_NRF_WriteReg(NRF_WRITE_REG+RF_SETUP,0x0f);  					//设置TX发射参数,0db增益,2Mbps,低噪声增益开启 
 	SPI_NRF_WriteReg(NRF_WRITE_REG+CONFIG,0x0e);    					//配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,发射模式,开启所有中断
 	NRF_CE_HIGH();                                                      /*CE拉高,进入发送模式*/
 //    delay_ms(1);                                                        //3 Delay(0x5555); //CE要拉高一段时间才进入发送模式
 	__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();               
 }

从机2主要配置通道1地址代码!!!

3.2.3 从机3发送代码

 void NRF_TX_Mode_BC(void)
 {
     NRF_CE_LOW();
 	SPI_NRF_WriteBuf(NRF_WRITE_REG+TX_ADDR,TX_ADDRESS2,TX_ADR_WIDTH);    //写TX节点地址 
 	SPI_NRF_WriteBuf(NRF_WRITE_REG+RX_ADDR_P0,RX_ADDRESS2,RX_ADR_WIDTH); //设置TX节点地址,主要为了使能ACK 
 	SPI_NRF_WriteReg(NRF_WRITE_REG+EN_AA,0x3f);     					//使能通道0的自动应答     
 	SPI_NRF_WriteReg(NRF_WRITE_REG+EN_RXADDR,0x3f); 					//使能通道0的接收地址  
 	SPI_NRF_WriteReg(NRF_WRITE_REG+SETUP_RETR,0x1a);					//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次
 	SPI_NRF_WriteReg(NRF_WRITE_REG+RF_CH,40);       				//设置RF通道为CHANAL
 	SPI_NRF_WriteReg(NRF_WRITE_REG+RF_SETUP,0x0f);  					//设置TX发射参数,0db增益,2Mbps,低噪声增益开启 
 	SPI_NRF_WriteReg(NRF_WRITE_REG+CONFIG,0x0e);    					//配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,发射模式,开启所有中断
 	NRF_CE_HIGH();                                                      /*CE拉高,进入发送模式*/
 //    delay_ms(1);                                                        //3 Delay(0x5555); //CE要拉高一段时间才进入发送模式
 	__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();               
 }

从机3主要配置通道2地址代码!!!

四、主机通道选择代码

 u8 NRF_Rx_Dat(u8 *rxbuf)
 {
 	u8 state;
	u8 RX_P_NO;
 	NRF_CE_HIGH();	 //进入接收状态
 	/*等待接收中断*/
 	while(NRF_Read_IRQ()==0)
 	{
		 NRF_CE_LOW();  	 //进入待机状态
 		/*读取status寄存器的值  */               
 		state=SPI_NRF_ReadReg(STATUS);
		//RX_P_NO=SPI_NRF_ReadReg(RF_CH);    
 		/* 清除中断标志*/      
 		SPI_NRF_WriteReg(NRF_WRITE_REG+STATUS,state);
 		/*判断是否接收到数据*/
 		if(state&RX_DR)                                 //接收到数据
 		{
			RX_P_NO = state & 0x0e; //获取通道号
			switch (RX_P_NO)
			{
			case 0x00:
 			SPI_NRF_ReadBuf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据
			SPI_NRF_WriteReg(FLUSH_RX,NOP);          //清除RX FIFO寄存器
			break; 
			case 0x02:
 			SPI_NRF_ReadBuf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据
			SPI_NRF_WriteReg(FLUSH_RX,NOP);          //清除RX FIFO寄存器
			break; 
			case 0x04:
 			SPI_NRF_ReadBuf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据
			SPI_NRF_WriteReg(FLUSH_RX,NOP);          //清除RX FIFO寄存器
			break; 
			default:
			SPI_NRF_WriteReg(FLUSH_RX,NOP);          //清除RX FIFO寄存器
				break;
			}
			return RX_DR;
 		}
 		else    
 		return ERROR;                    //没收到任何数据
   }
  
   return ERROR;                    //没收到任何数据
 }

去通过状态寄存器去判断它传输的通道。这段代码主要是判断是那个从机发过来

 NRF24L01模块是比较不稳定的模块。

(1)该模块的天线在PCB上,没有加功率芯片,属于传输距离最短的模块。空旷条件下,经过实测,2M传输速率下15         米,1M传输速率30米,250K传输速率50米。

(2)该模块的天线是外置天线,没有加功率芯片,传输距离比前者在每种速率下大概大了1倍的传输距离。

(3)​该模块既加了外置天线,又加了功放芯片,在250K传输速率下,传输距离可达1100米。

所以我们在选择通信模块的时候需要注意这些方面。希望对大家调试NRF24L01通信模块有帮助,亲测已经实现一主机多从机发送的实验!!!

  • 4
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值