NRF24L01+实现一对一数据双向传输
NRF24L01+实现一对一数据双向传输
- 目录
- 说明
- 带负载数据ACK的双向通信
- 配置NRF24L01+的收发程序
- 收发双方数据的处理
- 测试代码和结果
目录
说明
最近在diy四轴飞行器的时候,需要实现四轴和遥控器之间的双向通信。手头上用的模块是NRF24L01+和SI24R1,这两个芯片的引脚功能相同,不仅硬件上可以直接进行替换使用,程序往往还可以互用(因为还是有点差别),两个芯片的差别很小,其中一个是SI24R1的功率最大达到7dB,而NRF24L01+最大是0dB,这个在配置参数的时候要注意。
NRF24L01+和SI24R1都可以配置为发送或接收模式,为了减少打字的麻烦,下文全都以NRF24L01+来写。实现四轴和遥控器的双向通信,可以让NRF24L01+不断在收/发模式之间直接进行切换,小马哥的四轴用的就是这种方式,但我用HAL库实现这种方式的时候,会出现这种问题:两者可以进行双向的数据传输,但一会儿之后就不能传输了,我也不清楚是怎么回事。
后来查询芯片数据手册,仔细研究NRF24L01+的工作方式之后,发现NRF24L01+工作在ACK模式时,发送端发送数据给接收端时,接收端收到并检验数据无误后,会回复一个ACK信号给发送端,收到ACK的发送端就认为数据发送完成,并产生TX_DS中断,这就是一个应答机制。而接收端回复的ACK信号可以是选择带负载数据的,利用这一点,就可以把接收端要回传的数据发送回发送端,以此来实现双向数据传输。
带负载数据ACK的双向通信
要使用带负载数据的ACK信号(ACKPAYLOAD)需要配置FEATURE寄存器中的EN_ACK_PAY位,同时收发双方要开启动态负载长度(通过配置DYNPD和FEATURE寄存器来实现)。
配置NRF24L01+的收发程序
程序改自正点原子的实验例程。
接收方
NRF24L01_CE=0; NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH);//写RX节点地址NRF24L01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址 NRF24L01_Write_Reg(NRF_WRITE_REG+RF_CH,40); //设置RF通信频率 NRF24L01_Write_Reg(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0的有效数据宽度 NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f); //设置TX发射参数,0db增益,2Mbps,低噪声增益开启 NRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x01); //使能通道0的自动应答 NRF24L01_Write_Reg(NRF_WRITE_REG+FEATURE,0x06); //使能动态负载(收发数据)长度NRF24L01_Write_Reg(NRF_WRITE_REG+DYNPD,0x01); //使能通道0动态负载长度NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG, 0x0f); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式NRF24L01_CE=1;
发送方
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); //设置TX节点地址,主要为了使能ACKNRF24L01_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); //设置RF通道为40NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f); //设置TX发射参数,0db增益,2Mbps,低噪声增益开启 NRF24L01_Write_Reg(NRF_WRITE_REG+FEATURE,0x07); //使能动态负载(收发数据)长度NRF24L01_Write_Reg(NRF_WRITE_REG+DYNPD,0x01); //使能通道0动态负载长度NRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x01); //使能通道0的自动应答 NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG,0x0e); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式,开启所有中断NRF24L01_CE=1;//CE为高,10us后启动发送
以上配置经过测试是可以使用的,在NRF24L01+之间,SI24R1之间,NRF24L01和SI24R1之间都可以进行双向通信。
收发双方数据的处理
首先是写两个发送数据的函数(其实这两个函数是把数据写入到发送缓冲区,而不是实现数据的发送)
一个是发送端主动发送数据给接收端:
void nrf_txPacket(u8 *txbuf,u8 len)
{NRF24L01_CE=0;NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,len);//写数据到TX BUFNRF24L01_CE=1;
}
另一个是接收端回复带负载数据的ACK信号(把要回传的数据写入到发送缓冲区,等待接收端自动发送应答信号)
void nrf_txPacket_AP(u8 *txbuf,u8 len)
{NRF24L01_CE=0;NRF24L01_Write_Buf(W_ACK_PAYLOAD(0),txbuf,len);//写数据到TX BUFNRF24L01_CE=1;
}
然后是处理数据的函数,我是在中断回调函数里处理的
u8 sta = NRF24L01_Read_Reg(NRF_READ_REG + STATUS);if(sta & TX_OK){NRF24L01_CE = 0;NRF24L01_Write_Reg(NRF_WRITE_REG + STATUS,TX_OK); //清除发送完成标志·NRF24L01_Write_Reg(FLUSH_TX,0xff); //清除TX_FIFO//在这里对发送完的数据进行数据处理NRF_TX_DATA[0]++;NRF24L01_CE = 1;}if(sta & RX_OK){NRF24L01_CE=0;u8 len = NRF24L01_Read_Reg(R_RX_PL_WID);if(len>0 && len<33)//数据长度有效{NRF24L01_Read_Buf(RD_RX_PLOAD,NRF_RX_DATA,len);}nrf_txPacket_AP(NRF_TX_DATA,1);//发送ACK Payload,数据长度为1NRF24L01_Write_Reg(NRF_WRITE_REG + STATUS,RX_OK);//清除发送完成标志NRF24L01_Write_Reg(FLUSH_RX,0xff); //清除RX_FIFONRF24L01_CE=1;}if(sta & MAX_TX){NRF24L01_CE = 0;NRF24L01_Write_Reg(NRF_WRITE_REG+STATUS,MAX_TX);//清除达到最大重发标志NRF24L01_Write_Reg(FLUSH_TX,0xff); //清除TX_FIFONRF24L01_CE = 1;}
测试代码和结果
接收端的代码:显示接收端接收到的和发送出去的数据
while(1){LCD_ShowxNum(30+14*8,170,NRF_RX_DATA[0],3,16,0);LCD_ShowxNum(30+14*8,190,NRF_TX_DATA[0],3,16,0);delay_ms(1); t++;if(t==1000)//大约1s钟改变一次状态{t=0;LED0=!LED0;} }
发送端的代码:显示发送端发送的数据和接收到的数据
while(1){LCD_ShowxNum(30+14*8,170,NRF_RX_DATA[0],3,16,0);LCD_ShowxNum(30+14*8,190,NRF_TX_DATA[0]++,3,16,0);delay_ms(1); t++;if(t==1000)//大约1s钟改变一次状态{t=0;LED0=!LED0;nrf_txPacket(NRF_TX_DATA,1);}}
测试效果
最后,本人没什么写博客的经验,表达不够清晰,写的也比较水,为的是记录一下调试的经历,如果表述中有什么错误的地方欢迎各位大佬批评指正。想知道更详细的内容需要查阅一下数据手册,了解一下NRF24L01+/SI24R1的工作流程。
NRF24L01+实现一对一数据双向传输相关推荐
- 分包组包 北斗通信_一种利用北斗短报文实现第三方数据双向传输的方法与流程...
本发明涉及通信技术领域,特别涉及一种利用北斗短报文实现第三方数据双向传输的方法. 背景技术: 中国北斗卫星导航系统是中国自行研制的全球卫星导航系统,北斗RDSS是北斗系统区别于其他导航系统的特点之一, ...
- 基于NRF24L01的CAN数据透传
闲谈: 闲来无聊,恰好公司又经常用CAN数据的传输,自己觉得要是用无线传送多好,然后,就是一个奇想,就想做一个无线数据的透传,恰好身边又有NRF24L01,那就行动吧! 下面是NRF24L01 SPI ...
- 【STM32+cubemx】0026 HAL库开发:NRF24L01无线2.4G通信模块的应用
NRF24L01是NORDIC公司生产的一款无线通信通信芯片,可以工作在免费开放的2.4GHz频段:通信速率可以达到最高2Mbps:MUC可以使用SPI接口与它交互. 本节我们就来使用stm32驱动N ...
- 基于arduino与raspberry的远程数据采集系统
前言 该课题是毕业时做的一个远程数据采集课题,今天无意翻看到这份报告,不禁勾起满满的怀念.重新看了一遍报告,感觉做的确实是挺low的,但想起当时自己查了无数的资料,才完成这个设计,尤其是人在学校,然后 ...
- NRF24L01模块多发一收通信(STM32)
NRF24L01模块多发一收通信(STM32) 目录 NRF24L01模块多发一收通信(STM32) 前言 一.解决思路 二.实验过程 1.设备ID号定义 2.数据打包发送 3.数据接收拆解 总结 前 ...
- NRF24L01模块配置
发射数据时: (1)首先将nRF24L01配置为发射模式 (2)接着把接收节点地址TX_ADDR和有效数据TX_PLD按照时序由SPI口写入nRF24L01缓存区,TX_PLD必须在CSN为低 ...
- 外设驱动库开发笔记26:nRF24L01无线通讯驱动
现在无线在我们的生活中无处不在.而我们开发的物联网产品也大量使用无线通讯.在这一篇文章中,我们将讨论nRF24L01无线通讯模块驱动程序的开发与实现. 1.功能概述 nRF24L01是一款工作在2.4 ...
- 【STM32】NRF24L01模块的收发调试
NRF24L01 发送端.c文件 发送端.h文件 接收端.c文件 接收端.h文件 接收端main函数 总结: 这里我是用了两块板子来做通信实验,这里我就直接贴发送端和接收端的.c.h文件,一个是用标准 ...
- HAL库驱动NRF24L01实现数据传输
文章目录 1.NRF24L01介绍 2.驱动程序设计 1.根据原理图进行封装 2.cubemx配置 3.收发测试 4.源代码 本次使用正点原子精英开发板和野火MINI开发板进行采用NRF24L01的数 ...
最新文章
- 谷歌发布深度学习新算法,适用于真实机器人的技能学习
- 波士顿动力机器狗要去切尔诺贝利上班了
- InfoPath表单实战
- 电脑声音太小如何增强_感觉手机音量太小了?教你这样设置,声音立马大上许多...
- 大型网站系统与Java中间件实践pdf
- Git开发流程和工作流
- html5自动打印图片,html2canvas生成清晰的图片实现打印代码示例
- Current在Java里面_在C#中相当于Java System.currentTimeMillis()
- Bulma - 基于 Flexbox 的现代化的 CSS 框架
- 汇编语言上机考试三星题——判断一个不超过65535的整数是否为质数
- 管理感悟:测试的目的是什么
- GitLab上配置SSH Key
- python构建决策引擎_决策引擎与机器学习模型的集成 | 信数这么干(一)
- 基于冲突的搜索算法(CBS)个人笔记
- linux dumpe2fs命令
- K-mean 算法代码演示
- 第14周—项目1(3)二叉排序树
- 海信研发前端工程师面试经验总结
- 极坐标t1t2几何意义_复数与几何(一) 基本几何性质及应用
- 禁止查看写好的宏_??智能作业灯T5体验:不在孩子身边,也能辅导小朋友写作业...
热门文章
- thinkphp5 实现短信注册验证功能
- 谷歌的代码覆盖率最佳实践
- 唯众高职物联网应用技术专业解决方案
- solidworks批量图号分离_教你如何将SolidWorks2016图号名称分离到零件属性中
- Threejs实现键盘控制人物行走跳动/Capsule碰撞体(胶囊体)/碰撞检测(Octree八叉树)/游戏第三人称/镜头跟随人物移动
- 记录一下自己vscode的代码合并功能的使用
- CC00339.CloudKubernetes——|KuberNetes运维.V56|——|Prometheus.v01|自动发现.v01|创建secret|
- BMS中SOC的计算(一)
- 【自动驾驶模拟器AirSim快速入门 | 04】推理预测及模拟器运行
- Elasticsearch 8.X “图搜图”实战