nRF24L01+启用自动应答ACK及自动重发的实战分享
ACK模式(自动应答)功能的官方说明
当用W_TX_PAYLOAD命令对发送端TX FIFO写数据时,将数据打包后,数据包中包控制字段NO_ACK 标志位复位。接收端接收到一帧有效数据后, 产生RX_DR中断后,会自动发送一帧ACK信号,发送端接收到ACK信号,则自动清除TX FIFO数据并产生TX_DS发射中断,表明此次通信成功。
接收端在发送ACK信号时,取接收管道地址作为目标地址来发送ACK信号,所以发送端需要设置接收管道0地址与自身发送地址相同,以便接收ACK信号。
如果发送端在ARD时间内没有接收到ACK信号,则重新发送上一帧数据。当重发次数达到最大,仍没有收到确认信号时,发送端产生MAX_RT中断。MAX_RT中断在清除之前不能进行下一步的数据发送。所有中断通过对状态寄存器进行写操作来清除。PLOS_CNT寄存器在每产生一个MAX_RT中断后加1,用来记录当前频段下,丢失的数据包的数量。ARC_CNT寄存器记录当前数据重发的次数,在发送一包新数据时使其复位。最大重发次数与ARD时间通过SETUP_RETR寄存器来进行配置。接收端开启自动回复ACK信号由EN_AA寄存器来控制。
发送端每当发射一个新数据包,数据对应的PID自动加1,因此发送的相邻的两个数据包中,PID应互不相同。如果链路中连续几帧数据丢失,接收端接收到的连续两帧数据的PID可能相同。
接收端如果发现接收到数据与上一帧数据PID相同,则比对CRC,如果CRC也相同,则判断为上一帧数据的重发,将数据丢弃,并重新回复ACK信号。图4.4发送端第一次数据发送没有接收到ACK信号,进行重发后,接收到ACK信号,数据通信成功完成。
解读启用ACK模式必需的寄存器配置
这里只介绍与ACK模式相关的寄存器配置,默认理解为其他配置都正确的情况下。
发送方的必要配置
nRF24L01+的ACK自动应答功能,原理是在接收方收到数据后立刻自动回复给发送方一个ACK确认数据包,发送方如果收到确认的数据包,认为发送成功,否则认为本次失败,是否再次发送,决定于自动重发的配置。
那带来的疑问是,接收方收到数据后,在回复的时候,是怎样知道发送方的地址的呢?数据包中并没有携带地址,如果携带会多占用5个字节,影响了传输有效数据的相对速率。设计团队最后使用的是在发送时,先将发送方的接收通道0的接收地址设置为要发送的目标地址,这样执行完发送就立刻等待接收,并自己的地址是与目标地址一样的。接收方收到数据回复ACK的时候,就不需要知道发送方的地址,按照自己的地址作为目标地址发出即可。因自己处在发送状态,所以自己不会接收,而发送方这时刚好处在接收状态,地址刚好是接收方的地址,也是接收方回复时的目标地址,所以发送方可以收到回复的ACK数据。因此下面的这行配置必需存在:
spi_write_buf(RX_ADDR_P0, TX_ADDRESS, 5); //接收通道0地址和发射地址相同,等待接收来自接收方的ACK数据
ACK模式的整个工作过程中,自动重发功能为确保数据有效到达起了很大作用。因为无线电信号很难在任何环境下都十分稳定,也极容易受到各种干扰,那么如果一次发送没有收到ACK数据,就可以认为本次发送失败。接下来稍等一下可以再次发送,经过多次尝试,成功率就大大增加了。所以就要启用自动重发功能,当达到重发次数的上限的时候,仍然没有收到ACK数据,则宣告本轮发送彻底失败。因此下面的配置也是必需存在的:
spi_write_reg(SETUP_RETR, 0x15); //自动重发延时等待500us,自动重发5次,根据自己需要设置
SETUP_RETR寄存器的说明见下图(0x15的二进制是00010101):
接收方的必要配置
接收方为了可以在收到数据后,执行自动回复功能,需要开启相应的控制寄存器,否则无法实现自动回复,因为下面这行配置是必需存在的:
spi_write_reg(EN_AA, 0x01); //使能接收通道0的自动应答
如果启用了ACK功能,那么CRC校验功能就必须启用,因为需要避免接收到重复的数据包产生多次接收成功和造成多次回复的现象。因此下面的配置也是必需存在的:
spi_write_reg(CONFIG, 0x0F); //CRC使能,16位CRC校验,开机,接收模式
CONFIG寄存器的说明见下图(0x0F的二进制是00001111):
ACK模式的发送过程
发送方先置为发送模式,以上介绍的发送模式的寄存器也在置为发送模式时配置完毕。
接下来使用W_TX_PAYLOAD命令写入待发送的数据,参考代码如下:
CE = 0; //CE拉低,使能24L01配置
spi_write_buf(WR_TX_PLOAD, RF24Buf, TX_PLOAD_WIDTH); //写数据到TX FIFO,TX_PLOAD_WIDTH个字节
CE = 1; //CE置高,使能发送
模块在发送完发送缓冲区的数据后,自动立刻转入接收状态,并将自己的地址临时修改为刚才发送的目标地址(即接收方地址,因为接收方回复的时候,它的目标地址会是这个),等待接收方回复ACK,收到ACK后产生发送成功TX_DS(0x20)中断。
如果在SETUP_RETR寄存器设置的时间间隔内没有收到ACK回复,将再次发送,直到收到ACK或达到SETUP_RETR寄存器设置的最大发送次数。如达到最大发送次数则产生MAX_RT(0x10)中断,表示已经尝试发送到最大次数仍然没有成功。
以上状态都可通过读状态寄存器STATUS得到(其实单片机每次与模块通信,SPI指令返回的都是这个寄存器的值),下图是STATUS寄存器的说明:
有关nRF24L01+的ACK模式的调试重点就介绍到这里,其他关于nRF24L01+的问题请看本人博客的其他文章。
nRF24L01+启用自动应答ACK及自动重发的实战分享的更多相关文章
- nRF24L01+不能接收或接收偶尔异常等问题实战分享
nRF24L01+接收异常问题综述 在调试nRF24L01+无线收发模块的时候,最具标志性的环节就是在接收端可以收到数据.在实际应用调试中,会出现很多意想不到的情况,造成nRF24L01+模块接收端无 ...
- DWM1000 自动应答代码实现与实例
这一节继续继承之前帧过滤部分,首先补充一下关于帧过滤部分,如果将目标地址设置为0xFFFF,则同一个网络(物理频道与PANID 都相同),所有节点都应该收到这条信息,这个信息为广播信息,0xFFFF为 ...
- 创建Windows10无人值守(自动应答文件)教程
一.准备工作 系统要求: Windows10 1809版本 工具下载: 镜像:Windows10,任何一个版本都可以,我使用的是1909版本 ed2k://|file|cn_windows_10_bu ...
- Windows 7 SP1无人值守自动应答文件制作
使用U盘安装Windows系统时,很多人都会使用UltraISO工具来制作U盘启动盘,然后插入到电脑中加以安装.系统的安装过程中,需要一步一步手动选择或者输入配置,Windows是支持无人值守自动应答 ...
- C#-MVC开发微信应用(5)--自动应答系统-自动回复机器人
前几篇已经介绍菜单和有回复信息操作,下面我们就结合snf微信端管理页面,看一下什么才是自动应答系统. 定制的服务 对于微信服务号来说,最主要的功能是提供更好的服务.用户更方便的操作,以及更快的反馈响应 ...
- C# .net微信开发,开发认证,关注触发消息,自动应答,事件响应,自定义菜单
成为开发者 string[] ArrTmp = { "token", Request["timestamp"], Request["nonce&quo ...
- (转)C# .net微信开发,开发认证,关注触发消息,自动应答,事件响应,自定义菜单
原文地址:http://www.cnblogs.com/qidian10/p/3492751.html 成为开发者 string[] ArrTmp = { "token", Req ...
- shell脚本--expect自动应答
expect自动应答 TCL语言 需求1:远程登录到A主机,什么事情也不做 #! /usr/bin/env expect # 开启一个程序 spawn ssh root@192.144.213.11 ...
- expect自动应答
expect脚本 1. expect简介 expect是一个用来处理交互的命令.借助Expect,我们可以将交互过程写在一个脚本上,使之自动化完成. expect(自动应答) 基于TCL(Tool C ...
随机推荐
- 「SAP技术」SAP HU上面的'Obj.to Which HU Belongs'栏位初探
SAP HU上面的'Obj.to Which HU Belongs'栏位初探 HU02,创建一个新的HU, 保存之, HU03显示这个HU 189141203942, 其'obj.to Which H ...
- 【转载】Android N 完全不同以往的四个新特性
Google最近发布了Android的下一个版本,Android N的开发者预览版.此次预览版,可以让我们开发者在正式发布之前就测试代码,包括一些新的API,甚至于也可以提前反馈那些对于我们来说有些困 ...
- 微信小程序实现点击拍照长按录像功能
微信小程序实现点击拍照长按录像功能 代码里面注释写的都很详细,直接上代码.官方的组件属性中有触摸开始和触摸结束属性.本功能依靠这些属性实现. .wxml代码: <!-- 相机 pages/cam ...
- 示例:Oracle表锁、行锁模拟和处理
for update模拟锁表 --session 1 SQL> select * from tt for update; --session 2 SQL> update tt set id ...
- 小计C++中的引用和vector
声明引用的同时必须对其初始化,否则系统会报错,所以我们是无法这样使用 vector<int &> vec; 这条语句会报错,同时引用不是定义一个新的变量或对象,因此内存不会为引用开 ...
- go语言设计模式之memento
memento.go package memento import ( "fmt" ) type State struct { Description string } type ...
- NLP中的数据增强
相关方法合集见:https://github.com/quincyliang/nlp-data-augmentation 较为简单的数据增强的方法见论文:https://arxiv.org/pdf/1 ...
- 不用输入ssh -i命令行即可携带pem文件快速登录的方法
如果要登录的服务器只允许pem认证 每次输入ssh -i xxxx.pem 用户@ip 地址 就很烦 这里有个一劳永逸的方法: 进入到自己的用户目录,例如/home/me 把pem文件放在当前目录 ...
- Paper | Non-local Neural Networks
目录 1. 动机 2. 相关工作 3. Non-local神经网络 3.1 Formulation 3.2 具体实现形式 3.3 Non-local块 4. 视频分类模型 4.1 2D ConvNet ...
- 开放平台API接口安全策略汇总
在设计开放平台接口过程中,往往会涉及接口传输安全性相关的问题,本文对接口加密及签名的相关知识做了一个总结,在方便自己查阅的同时也分享给大家做一些参考. 接口安全性问题思考 接口安全性问题主要来源于几方 ...