完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
nRF24L01 动态数据长度
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寄存器】 [tr]寄存器功能[/tr]
基础配置就这些,只是添加了四行代码 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:%drn",RX_pipe,length); //打印信息 for(i = 0; i < length; i++){ printf("%x ",RX_FIFO_Buff); } NRF_CE_HIGH; //重新拉高CE,进入接收模式,准备接收下一个数据 } 当【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模块的使用也就全部写完了 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1771 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1619 浏览 1 评论
1070 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
724 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1673 浏览 2 评论
1936浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
729浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
569浏览 3评论
594浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
552浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 19:26 , Processed in 0.891850 second(s), Total 79, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号