stm32【 NRF24L01多通道、动态数据、主从一体(3)】

nRF24L01 动态数据长度

回顾
NRF 1对1通讯
NRF多通道通讯
在前面两篇文章里,实现的主从一体的单通道,多通道通讯,接下来讲解关于动态数据长度的配置,是在多通道的基础是进行修改的,而且本篇文章是作为nRF24L01模块调试的最终篇章,将实现单/多通道,动态数据的主从一体的所有功能

在前面的文章里,都是接收特定长度的数据包,数据个数通过【STATIC_PLOAD_LENGTH】设置,当接收到这么多个数据后,会在IRQ输出一个低电平,触发中断
而动态数据长度,指的是接收不同长度的数据包,接收到数据后就会在IRQ输出一个低电平,触发中断,此时得先知道本次接收的数据包内有n个有效数据,再读出n个数据
注意:无论是静态还是动态长度的数据包,有效数据不能超过32个(byte)

nRF动态数据长度配置

【void NRF_Config(void)】函数修改成下面给出的▼

void NRF_Config(void)
{
	NRF_SPI_Config();
	
	//拉低CE,注意:需要将CE拉低,使其进入待机或者掉电模式才能读/写nRF寄存器
	NRF_CE_LOW;
	
	//初始化NRF(看数据手册)
	NRF_SPI_WriteReg(W_REGISTER | SETUP_AW, 0x03);							//配置通信地址的长度,默认值时0x03,即地址长度为5字节
	NRF_SPI_WriteReg(W_REGISTER | SETUP_RETR, 0x15); 						//自动重发延迟为500+86us,重发次数5次
	NRF_SPI_WriteReg(W_REGISTER | RF_SETUP, 0x07);   						//设置发射速率为1MHZ,发射功率为最大值0dB
	NRF_SPI_WriteReg(W_REGISTER | RF_CH, 30);        						//设置通道通信频率,工作通道频率可由以下公式计算得出:Fo=(2400+RF_CH)MHz.并且射频收发器工作的频率范围从2.400-2.525GHz

#if RX_MULIT_CHANNEL
//---------------------------PRX:多通道配置----------------------------------------------------------------------------	
																				//通道0和1完整赋值,通道2-5只能赋值地址的第一个(最低byte)
	NRF_SPI_WriteBuf(W_REGISTER | RX_ADDR_P0, RX_ADDRESS_0, ADDRESS_WIDTH); 	//配置PRX接收通道0的接收数据的地址
	NRF_SPI_WriteBuf(W_REGISTER | RX_ADDR_P1, RX_ADDRESS_1, ADDRESS_WIDTH); 	//配置PRX接收通道1的接收数据的地址
	NRF_SPI_WriteBuf(W_REGISTER | RX_ADDR_P2, RX_ADDRESS_2, 1); 				//配置PRX接收通道2的接收数据的地址
	NRF_SPI_WriteBuf(W_REGISTER | RX_ADDR_P3, RX_ADDRESS_3, 1); 				//配置PRX接收通道3的接收数据的地址
	NRF_SPI_WriteBuf(W_REGISTER | RX_ADDR_P4, RX_ADDRESS_4, 1); 				//配置PRX接收通道4的接收数据的地址
	NRF_SPI_WriteBuf(W_REGISTER | RX_ADDR_P5, RX_ADDRESS_5, 1); 				//配置PRX接收通道5的接收数据的地址

	NRF_SPI_WriteReg(W_REGISTER | EN_AA, 0x3F);      						//接收数据后,允许所有通道自动应答
	NRF_SPI_WriteReg(W_REGISTER | EN_RXADDR, 0x3F);  						//允许所有通道接收数据

//---------------------------PRX:接收数据长度配置----------------------------------------------------------------------------	
	#if DYNAMIC_PLOAD_LENGTH //动态长度
		NRF_SPI_WriteReg(W_REGISTER | FEATURE, 0x06);   						//配合DPL功能使用
		NRF_SPI_WriteReg(W_REGISTER | DYNPD, 0x3f);    							//使能所有通道的DPL功能
	#else //固定长度,接收的数据到达STATIC_PLOAD_LENGTH长度时,才会触发RX_DS中断
		NRF_SPI_WriteReg(W_REGISTER | RX_PW_P0, STATIC_PLOAD_LENGTH);
		NRF_SPI_WriteReg(W_REGISTER | RX_PW_P1, STATIC_PLOAD_LENGTH);
		NRF_SPI_WriteReg(W_REGISTER | RX_PW_P2, STATIC_PLOAD_LENGTH);
		NRF_SPI_WriteReg(W_REGISTER | RX_PW_P3, STATIC_PLOAD_LENGTH);
		NRF_SPI_WriteReg(W_REGISTER | RX_PW_P4, STATIC_PLOAD_LENGTH);
		NRF_SPI_WriteReg(W_REGISTER | RX_PW_P5, STATIC_PLOAD_LENGTH);
	#endif
//---------------------------PTX:多通道配置------------------------------------------------------------------------	
	//发送通道地址,由于是多通道,在发送函数里选择配置


#else
//---------------------------PRX:单通道配置------------------------------------------------------------------------	
	NRF_SPI_WriteBuf(W_REGISTER | RX_ADDR_P0, RX_ADDRESS_0, ADDRESS_WIDTH); 	//配置本机接收通道0的接收数据的地址
	NRF_SPI_WriteReg(W_REGISTER | EN_AA, 0x01);      						//接收数据后,只允许频道0自动应答
	NRF_SPI_WriteReg(W_REGISTER | EN_RXADDR, 0x01);  						//只允许频道0接收数据
	
//---------------------------PRX:数据接收长度配置----------------------------------------------------------------------------	
	#if DYNAMIC_PLOAD_LENGTH	//动态数据长度
		NRF_SPI_WriteReg(W_REGISTER | FEATURE, 0x06);   						//配合DPL功能使用
		NRF_SPI_WriteReg(W_REGISTER | DYNPD, 0x01);    							//使能通道1的DPL功能
	#else	//固定数据长度
		NRF_SPI_WriteReg(W_REGISTER | RX_PW_P0, STATIC_PLOAD_LENGTH);
	#endif
//---------------------------PTX:单通道配置------------------------------------------------------------------------	
	//发送通道地址,由于是单通道,在这里配置一次就可以了(默认通道0)
	NRF_SPI_WriteBuf(W_REGISTER | TX_ADDR, RX_ADDRESS_0, ADDRESS_WIDTH);    	//发送的数据包中被一块打包进去的接收端NRF的接收通道的地址

#endif

	NRF_SPI_WriteReg(W_REGISTER | CONFIG, 0x0C | PWR_UP | PRIM_RX);   			//默认处于接收模式

	NRF_CE_HIGH;
	delay_ms(2);

}

这是由多通道的nRF配置函数修改来的,分别在【PRX:多通道配置】和【PRX:单通道配置】里再添加一个判断【DYNAMIC_PLOAD_LENGTH】,将单/多通道的固定数据长度和动态数据长度划分开来

当【DYNAMIC_PLOAD_LENGTH = 0】,单/多通道的数据长度配置和原来的一样
当【DYNAMIC_PLOAD_LENGTH = 1】,单/多通道只需要配置两个寄存器,分别是【FEATURE寄存器】和【DYNPD寄存器】

寄存器功能
FEATURE启动动态有效数据和自动应答等功能
DYNPD启动各个通道以动态有效数据对数据包进行接收的功能

详细的请看数据手册9.1章节
基础配置就这些,只是添加了四行代码

nRF数据发送(动态数据长度)

和固定数据长度不同,动态数据长度除了要给出接收通道地址和待发送的数组以外,还需要给出本次发送多少个数据,因此创建一个新的发送函数

/********************************************************************************
  * @brief  PTX模式下发送一个可变长度的数据包
  * @param  RX_ADDRESS_X	发送到的通道地址,在单通道模式下该值无效,默认通过通道0发送
  * @param	TX_BUFF			待发送的数据缓冲区
  * @param	length			数据个数
  * @retval none
  *******************************************************************************/
void NRF_SendPacket_DPL(u8 *RX_ADDRESS_X,u8 * TX_BUFF, u32 length)
{
	NRF_TX_Mode();

	NRF_CE_LOW;																//拉低CE,进入待机模式,准备开始往NRF中的寄存器中写入数据
#if RX_MULIT_CHANNEL
//---------------------------多通道发送地址选择---------------------------------------------------------------
	//RX_ADDRESS_X:PTX选择发送到PRX的哪一个通道
	NRF_SPI_WriteBuf(W_REGISTER | TX_ADDR, RX_ADDRESS_X, ADDRESS_WIDTH);
	//PTX使用pipe0来接收PRX的Auto-ACK信号
	//所以将RX_ADDRESS_X填入pipe0,这样才能对比Auto-ACK附带的通道地址
	//在退出PTX时要将RX_ADDRESS_0赋值给RX_ADDR_P0
	NRF_SPI_WriteBuf(W_REGISTER | RX_ADDR_P0, RX_ADDRESS_X, ADDRESS_WIDTH); 
#else //---------------------------单通道发送地址------------------------------------------------------------	
		//在NRF_Config里设置一次就行
#endif

	NRF_SPI_WriteBuf(WR_TX_PLOAD, TX_BUFF, length); 						//将数据写入TX端的FIFO中,写入的个数与TX_PLOAD_WIDTH设置值相同
	NRF_CE_HIGH;															//拉高CE,准备发射TX端FIFO中的数据
																			//CE拉高后,nRF自动延迟130us后,发送数据
}

这个函数和上一篇NRF多通道通讯给出的【void NRF_SendPacket(u8 *RX_ADDRESS_X,u8 *TX_BUFF)】函数基本是一致的,只是【NRF_SPI_WriteBuf(WR_TX_PLOAD, TX_BUFF, length);】这一句代码,使用的是传递进去的参数【length】,而不是【STATIC_PLOAD_LENGTH】

在写这篇文章的时候想到,其实这两个函数是可以写成一个函数的,不过发送和接收函数都是要看具体的应用来写,就没有修改了,这里只是提供一个思路罢了

nRF数据接收(动态数据长度)

在固定长度的情况下,读出数据的个数是知道的,
直接调用指令【RD_RX_PLOAD】就能读出数据▼

NRF_SPI_ReadBuf(RD_RX_PLOAD,RX_FIFO_Buff,STATIC_PLOAD_LENGTH);

而动态数据长度下,要用另一条指令【R_RX_PL_WID】先读出本次数据包内的有效数据个数,再调用指令【RD_RX_PLOAD】从RX_FIFO内读出指定个数的数据,因此接收函数修改成这样▼

/********************************************************************************
  * @brief  PRX模式下从RX_FIFO中接收一个数据包
			同时读出通道值
  * @param  none
  * @retval none
  *******************************************************************************/
void NRF_ReceivePacket(void)
{
	u8 i;
	u32 length;
	
	NRF_CE_LOW;
	
#if DYNAMIC_PLOAD_LENGTH
	length = NRF_SPI_ReadReg(R_RX_PL_WID);
	NRF_SPI_ReadBuf(RD_RX_PLOAD,RX_FIFO_Buff,length);				//从RX端的FIFO中读取数据,并存入指定的区域,注意:读取完FIFO中的数据后,NRF会自动清除其中的数据
#else
	length = STATIC_PLOAD_LENGTH;
	NRF_SPI_ReadBuf(RD_RX_PLOAD,RX_FIFO_Buff,STATIC_PLOAD_LENGTH);	//从RX端的FIFO中读取数据,并存入指定的区域,注意:读取完FIFO中的数据后,NRF会自动清除其中的数据
#endif

	RX_pipe = (status & 0x0E) >> 1;									//读取通道值
	
	printf("pipe%d  length:%d\r\n",RX_pipe,length);					//打印信息
	for(i = 0; i < length; i++){
		printf("%x ",RX_FIFO_Buff[i]);
	}
	
	NRF_CE_HIGH;													//重新拉高CE,进入接收模式,准备接收下一个数据
}

当【DYNAMIC_PLOAD_LENGTH = 0】时和之前的一样
当【DYNAMIC_PLOAD_LENGTH = 1】时,调用指令【R_RX_PL_WID】得到长度后,再读取数据

nRF24L01动态数据长度总结

本篇文章再NRF多通道通讯基础上修改了两个函数,并且新增加一个数据发送函数

void NRF_Config(void);			//nRF初始化
void NRF_ReceivePacket(void);
void NRF_SendPacket_DPL(u8 *RX_ADDRESS_X,u8 * TX_BUFF, u32 length);	//发送动态长度有效数据包

实现动态数据长度的功能,在主函数使用动态数据长度功能时将数据个数也一并传参就行了

	NRF_SendPacket_DPL(RX_ADDRESS_2,pack,sizeof(pack));

到此,对于nRF24L01模块的使用也就全部写完了

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
### 回答1: STM32nRF24L01是两种常用的嵌入式系统开发工具。STM32是一款由意法半导体(STMicroelectronics)生产的32位微控制器,它以其高性能、低功耗和丰富的外设接口而受到广泛应用。nRF24L01是一款射频收发器,由Nordic Semiconductor(北欧半导体)开发,适用于低功耗无线通信应用。 在使用STM32nRF24L01进行双向通信时,可以利用nRF24L01的射频模块与STM32进行连接。首先,在STM32上配置SPI(串行外围设备接口)来控制nRF24L01的操作。然后,通过STM32的GPIO(通用输入输出)口和nRF24L01的I/O口进行相互连接。 一般而言,双向通信的实现可分为发送和接收两个步骤。在发送端,STM32将待发送的数据通过SPI接口传输到nRF24L01的发送缓冲区,然后nRF24L01会将这些数据编码成射频信号,并通过天线发送出去。在接收端,nRF24L01通过接收天线捕获由发送端发出的射频信号,然后解码并将数据发送到STM32的接收缓冲区,最后STM32通过SPI接口读取这些数据并进行下一步的处理。 通过这种方式,STM32nRF24L01的双向通信就得以实现。我们可以根据具体的应用需求,使用STM32来控制nRF24L01的发送和接收,实现从一个设备向另一个设备发送数据,同时也可以接收另一个设备发送的数据。这种双向通信方式在很多无线通信应用中得到了广泛应用,如远程遥控、无线传感器网络等。 总的来说,STM32nRF24L01的双向通信应用范围广泛,可以满足各种无线通信需求。它们的结合为我们提供了一种强大而灵活的通信解决方案,使得嵌入式系统开发更加便捷和高效。 ### 回答2: STM32NRF24L01双向通信是指使用STM32微控制器与NRF24L01无线模块进行双向数据传输的方式。 首先,STM32是一款强大的32位ARM微控制器,它具备丰富的外设和高性能的运算能力,广泛应用于嵌入式系统和物联网领域。 NRF24L01是一种低功耗无线通信模块,基于2.4GHz射频技术,能够提供高速的数据传输和可靠的通信。它具备双向通信的能力,可以在STM32与其他设备之间进行双向数据传输。 要实现STM32NRF24L01的双向通信,首先需要将NRF24L01模块连接到STM32的GPIO引脚,并通过SPI接口进行通信。然后,使用STM32的软件开发工具,编写程序控制STM32NRF24L01进行数据交互。 在通信过程中,STM32可以发送指令或数据给NRF24L01模块,并通过无线信道传输到其他设备。同时,STM32也可以接收来自其他设备通过NRF24L01发送的数据。这样就实现了STM32NRF24L01之间的双向通信。 双向通信可以用于各种应用,例如智能家居系统中的传感器数据采集和控制命令发送,远程监控系统中的实时视频传输和控制指令发送等等。通过STM32NRF24L01的双向通信,可以实现设备之间的信息交互和互动。 ### 回答3: STM32nRF24L01都是无线通信领域的重要组件,可以实现双向通信。 STM32是一款具有强大性能和丰富外设的微控制器。它具有高性能的处理能力和丰富的外设资源,可以支持各种应用需求。在无线通信方面,STM32可以通过串口、SPI等接口与其他无线模块进行通信。 而nRF24L01是一款低功耗、高性能的2.4GHz无线收发器。它采用射频技术,能够实现远距离无线通信。nRF24L01提供了丰富的功能,如自动应答、频道设置、数据包重发等,使其适用于各种无线通信应用。 当STM32nRF24L01配合使用时,可以实现双向的无线通信。STM32作为主控芯片,通过SPI接口与nRF24L01进行通信,发送和接收数据。nRF24L01作为无线收发器,负责将数据从一个节点发送到另一个节点。这样,两个节点之间就可以实现双向的数据通信。 通过STM32nRF24L01的组合,我们可以实现许多应用,如智能家居中的无线传感器网络、远程控制设备的无线通信、车载系统中的数据传输等。双向通信的实现可以满足实时性要求高、数据交互频繁的应用场景。 总之,STM32nRF24L01的配合可以实现双向的无线通信,提供了广泛的应用潜力,使得我们可以在无线通信领域中进行更多的创新和应用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值