STM32
登录
直播中
王桂英
7年用户
1347经验值
私信
关注
[问答]
请问一下nrf2401模块的接口有哪几种呢
开启该帖子的消息推送
接口
模块
VCC/GND的管脚有何呢?
怎样才能准确知道是哪一种事件触发了IRQ呢?
回帖
(1)
侯晓萃
2021-12-17 09:21:18
一、接口介绍
以TB上最常见最便宜的模块为例。
左边的这个型号最常见,最便宜,大约3/4块钱一个,双排8针,2.54mm间距,模块尺寸比右边那个大;
右边这个也不少,稍贵,大约6/7块钱一个,单排8针,1.27mm间距,带邮票孔,体积非常小巧,做工我感觉要比前一个好些;
除此之外,这两种功能上没任何区别。
都是板载nrf24l01+单芯片,没有PA(射频功率放大)芯片,功率不大,空旷通信距离百米左右。
根据你自己的实际情况选择:
如果你【对成本不敏感】且【打算自己做板】且【希望板子做的小巧漂亮】,推荐右边这个;
除此之外一律选择左边这个;
根据我自己的经验,列出一些关于硬件使用上的问题(对上面两种型号均适用):
模块供电【一定/必须/不能】超过3.6V,如果你不小心接了5V供电,哪怕就一会儿,请节哀,不要问我是怎么知道的(╥╯^╰╥)。
除VCC和GND之外,其余6个pin却是兼容5V电平的,这也是为什么arduino可以导线直连的方式驱动它的原因。
除【买了便宜到超越底线的模块】之外,不要随便怀疑模块硬件有问题,一个模块能持续多年大量出货且不用升级换代,足以说明模块的稳定性。
所有管脚直连arduino的对应管脚即可,无需【串联】电阻。
用稳压芯片引出的3.3V供电可以直接给模块使用,除供电端极度不稳定之外,几乎不需要并联电容。
如果你用的是带PA的模块,工作电流峰值能达到一百几十毫安,要特别注意供电端的带载能力是否足够。
下面来说说除VCC/GND之外其余6个管脚的作用,可以先看一下上图中的那个管脚功能表,再看下文。
我们的程序要使用nrf24l01+,包括配置工作模式/查询工作状态/发送数据/接收数据,全部是通过这6个管脚来和模块进行交互的。
这6个管脚可以分为3组:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
CSN/SCK/MOSI/MISO算一组,是
SPI接口
,
往模块里送数据/从模块里读数据
都是使用SPI来进行的。
这里所说的数据有2个含义,即可以是我们打算向外界真实发送的数据,也可以是给这个模块自身的配置数据,也就是它内部各个寄存器的值。
从底层来说,这些数据就是一串0101,一打眼没什么区别,直接丢给你你也看不出来。
那nrf24l01+如何知道这一串0101代表什么含义呢? 当然是约定好协议格式啦:
不管这一串bit流有多长,一律按8bit即单字节为基本单元进行格式划分。
nrf24l01+规定,双方在传输字节时,必须高位bit优先输出,即输出顺序是: bit7-bit6-bit5-bit4-bit3-bit2-bit1-bit0。
CSN一旦拉低,模块的SPI接口被使能,同时也代表数据交换【或者叫“一次通信过程”吧】的开始;
主机从MOSI输出的第一个字节被叫做【
命令字
】,这个字节的含义是让模块知道主机想要做什么,例如读寄存器/写寄存器/写入待发送数据/读入已接收数据等等;
以写寄存器为例子,按照一般逻辑,不能只告诉我你想写寄存器,总还得告诉我你想写哪个吧,即必须还要传给我
寄存器的地址
。
二、命令字
nrf24l01+内部一共30个寄存器,编址0x00-0x1D,不多不少;
主机能做的事情也不多,读写寄存器,读写数据等等,总共十多项;
一个字节总共可以表示256种情况,不算少;
以上3者一结合,为了提高传输效率,于是砖家在设计nrf24l01+命令字的时候取了个巧,将代表【操作类型】的信息和代表【地址属性】的信息整合到一个字节中,即是【
命令字
】。
于是【命令字】从【
编码格式
】上分,一共有两大类:【 只带操作信息不需要地址信息的 】/【 操作信息地址信息都要有的 】。
下图中的3条命令就是这类复合命令字的典型。
以上图中读寄存器命令 R_REGISTER 为例,
操作码是0x00;
寄存器地址用bit4-bit0来表示,前面说过寄存器地址的最大值不过是0x1D, 5个bit足够容纳了。
于是修改0x1D寄存器的命令字应该是: 0x00+0x1D = 0x1D。
主机端在MOSI脚输出命令字的同时, nrf24l01+也没闲着,通过MISO脚也输出了从机端的第1个字节。
这个字节是有意义的,叫做【
状态字
】,是模块内部名为
STATUS
(地址0x07)寄存器数据的副本。
为什么偏偏选这个这个寄存器的值输出呢? 看一下这个寄存器的位值说明:
上面的位值表示了模块在工作过程中的一些关键性的状态数据,包括:
数据是否已经发送成功/是否发送失败/是否收到了外界的新数据/新数据来自哪个pipe/数据缓冲区是否已被写满
我们的程序在运行时一定会非常频繁的要获知这些状态,【 状态字 】给我们提供了某种福利:
不需要专门使用【命令字(0x00+0x07=0x07)】去读取STATUS,任何一次与模块的交互过程都能立即得到STATUS的值。
当然你非要使用读寄存器的方式获取STATUS也是可以的,就是效率低一点儿。
【命令字】和【状态字】过后,从第二个字节开始,后面都是数据字节。而数据字节的流向就只是单向的了。
【命令字】按照【
数据流向
】划分的话,可以分为3类:
一类是 给nrf2401送数据 ,比如写寄存器/写入待发送数据;
一类是 从nrf2401里面拿数据 ,比如读寄存区/读出其他模块发来的数据;
最后一类是 没有数据 ,只有命令,比如FLUSH_TX/FLUSH_RX只是通知模块清空内部数据缓冲区,明显不需要提供数据。
不存在既要给模块送数据同时也要从模块里读出数据的情况,所以说 数据流向是单向的 。
对于R_REGISTER命令,数据从模块流出,于是有效数据在MISO这根线上,MOSI上的数据就无所谓了;
同理,对于W_REGISTER命令,数据从主机流入模块,有效数据在MOSI这根线上,MISO上有啥无所谓;
绝大部分命令只带一个字节的数据就行了,个别情况需要附带多个字节的数据,以W_REGISTER为例:
数据通道pipe0的地址最长5个字节,在nrf2401内部只给这个pipe0_adr寄存器分配了1个寄存器地址而不是5个。
这个寄存器地址是0x0A,所以我们可以认为0x0A是一个长度为5字节的寄存器。
假设我们要给pipe0设置的地址为: 0xA4A3A2A1A0,拆开看从高到低5字节:0xA4 0xA3 0xA2 0xA1 0xA0
前面说过,SPI传输时字节内部高位bit优先输出,而协议规定传输多字节数据时,【低字节优先】输出。
于是MOSI信号线上字节流的顺序是这样的: CMD-A0-A1-A2-A3-A4
最后,数据传输完毕,CSN要拉高,即代表模块的SPI断开了主机的连接,也让nrf2401知晓一条命令结束了。
这个地方必须提醒,CSN拉高是必须的,哪怕你有很多命令排队等着操作模块,每条命令的写入都要遵守: 【CSN拉低-数据传输-CSN拉高】这条规定。
啰嗦了一大堆话,一张图足以代表一切:
解读一下这张图对我们
写程序
有什么用:
模块要求MOSI/MISO在SCK上升沿的时候输出bit,不管是软件模拟SPI还是硬件SPI要特别注意这一点,尤其是stm32这类SOC当主控时,它的SPI功能非常繁多,
配置SPI工作模式
的时候要特别注意
两条操作命令之间要在CSN高电平时添加适当延时
上图红框标出的Tcwh,这个时间代表上一条命令结束后,下条命令开始前,必须要有个恢复时间,防止误动作。
这个时间不要少于【100纳秒】,保守起见,建议
至少延时【500纳秒】
。
关于SPI接口,最后再说一下SCK时钟频率的问题:
nrf2401模块的时钟频率最高可以到10MHz,但保守起见,我们实际使用是建议时钟速度不要超过8M, 留一些余量总是好的 。
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
CE 可以单独算一组,这个管脚和 nrf2401射频模块的工作状态 有关。
当nrf2401被配置成PTX时,我们通过SPI写入要对外发送的数据之后,模块并不会立即启动发送,
我们必须再拉高CE管脚并使其高电平保持至少10微秒(10微秒过后,可以拉低也可以继续保持高电平),
模块才会开启射频模块,进入【
发送状态
】,开始发送数据。
当nrf2401被配置成PRX时,同样模块也不会立即启动射频模块进入【接收状态】
,
我们必须拉高CE并使其一直保持高电平,模块才会进入【接收状态】开始监听数据。
任意时刻,只要CE被拉低了,PRX会立即从【接收状态】退出到待机状态。
这只是CE管脚的基本用处,更多的细节我们后面在讲完【发送/接收缓冲区】以及【工作状态图】之后再说。
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
三、IRQ
IRQ 也单独算一组,这个管脚如其名,是模块用来通知主机【
数据发送/数据接收相关的紧急事件
】的快捷通道。
相对于单片机的运行速度来说,nrf2401是比较慢的,8M的SPI时钟下,主机要对外发送32字节数据,
只需要不到40微秒就能将数据全部塞给模块,而模块想要将这些数据发送完毕,需要的时间却是要多得多。
主机当然可以在写完数据之后,一遍遍的询问模块数据是否发送完成,但同时主机也不可能去干别的事情了,所以必须要使用中断通知的方式来减轻主机的压力。
主机写完数据之后就可以去忙别的了,后续发送过程/成功确认/发送失败确认的一系列工作交给模块自主完成,一旦结果出来之后,模块立即将IRQ管脚拉低。
主机端一般会将自己的外部中断管脚和模块的IRQ管脚连在一起,一旦IRQ管脚被模块置为有效,主机端的外部中断会立即触发,然后就可以在中断函数中访问模块,查看发生了什么。
这中 紧急事件只有3种 : 【数据发送成功】/【数据发送失败且已经多次失败】/【收到其他模块发来的新数据】
当中任意一个单独发生或任意多个同时发生,都会触发IRQ,所以主机程序在获知中断发生之后,必须在读取一遍模块内部的STATUS寄存器才能准确知道是哪一种事件触发了IRQ。
关于IRQ更细致的问题,后面章节中在讨论。
一、接口介绍
以TB上最常见最便宜的模块为例。
左边的这个型号最常见,最便宜,大约3/4块钱一个,双排8针,2.54mm间距,模块尺寸比右边那个大;
右边这个也不少,稍贵,大约6/7块钱一个,单排8针,1.27mm间距,带邮票孔,体积非常小巧,做工我感觉要比前一个好些;
除此之外,这两种功能上没任何区别。
都是板载nrf24l01+单芯片,没有PA(射频功率放大)芯片,功率不大,空旷通信距离百米左右。
根据你自己的实际情况选择:
如果你【对成本不敏感】且【打算自己做板】且【希望板子做的小巧漂亮】,推荐右边这个;
除此之外一律选择左边这个;
根据我自己的经验,列出一些关于硬件使用上的问题(对上面两种型号均适用):
模块供电【一定/必须/不能】超过3.6V,如果你不小心接了5V供电,哪怕就一会儿,请节哀,不要问我是怎么知道的(╥╯^╰╥)。
除VCC和GND之外,其余6个pin却是兼容5V电平的,这也是为什么arduino可以导线直连的方式驱动它的原因。
除【买了便宜到超越底线的模块】之外,不要随便怀疑模块硬件有问题,一个模块能持续多年大量出货且不用升级换代,足以说明模块的稳定性。
所有管脚直连arduino的对应管脚即可,无需【串联】电阻。
用稳压芯片引出的3.3V供电可以直接给模块使用,除供电端极度不稳定之外,几乎不需要并联电容。
如果你用的是带PA的模块,工作电流峰值能达到一百几十毫安,要特别注意供电端的带载能力是否足够。
下面来说说除VCC/GND之外其余6个管脚的作用,可以先看一下上图中的那个管脚功能表,再看下文。
我们的程序要使用nrf24l01+,包括配置工作模式/查询工作状态/发送数据/接收数据,全部是通过这6个管脚来和模块进行交互的。
这6个管脚可以分为3组:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
CSN/SCK/MOSI/MISO算一组,是
SPI接口
,
往模块里送数据/从模块里读数据
都是使用SPI来进行的。
这里所说的数据有2个含义,即可以是我们打算向外界真实发送的数据,也可以是给这个模块自身的配置数据,也就是它内部各个寄存器的值。
从底层来说,这些数据就是一串0101,一打眼没什么区别,直接丢给你你也看不出来。
那nrf24l01+如何知道这一串0101代表什么含义呢? 当然是约定好协议格式啦:
不管这一串bit流有多长,一律按8bit即单字节为基本单元进行格式划分。
nrf24l01+规定,双方在传输字节时,必须高位bit优先输出,即输出顺序是: bit7-bit6-bit5-bit4-bit3-bit2-bit1-bit0。
CSN一旦拉低,模块的SPI接口被使能,同时也代表数据交换【或者叫“一次通信过程”吧】的开始;
主机从MOSI输出的第一个字节被叫做【
命令字
】,这个字节的含义是让模块知道主机想要做什么,例如读寄存器/写寄存器/写入待发送数据/读入已接收数据等等;
以写寄存器为例子,按照一般逻辑,不能只告诉我你想写寄存器,总还得告诉我你想写哪个吧,即必须还要传给我
寄存器的地址
。
二、命令字
nrf24l01+内部一共30个寄存器,编址0x00-0x1D,不多不少;
主机能做的事情也不多,读写寄存器,读写数据等等,总共十多项;
一个字节总共可以表示256种情况,不算少;
以上3者一结合,为了提高传输效率,于是砖家在设计nrf24l01+命令字的时候取了个巧,将代表【操作类型】的信息和代表【地址属性】的信息整合到一个字节中,即是【
命令字
】。
于是【命令字】从【
编码格式
】上分,一共有两大类:【 只带操作信息不需要地址信息的 】/【 操作信息地址信息都要有的 】。
下图中的3条命令就是这类复合命令字的典型。
以上图中读寄存器命令 R_REGISTER 为例,
操作码是0x00;
寄存器地址用bit4-bit0来表示,前面说过寄存器地址的最大值不过是0x1D, 5个bit足够容纳了。
于是修改0x1D寄存器的命令字应该是: 0x00+0x1D = 0x1D。
主机端在MOSI脚输出命令字的同时, nrf24l01+也没闲着,通过MISO脚也输出了从机端的第1个字节。
这个字节是有意义的,叫做【
状态字
】,是模块内部名为
STATUS
(地址0x07)寄存器数据的副本。
为什么偏偏选这个这个寄存器的值输出呢? 看一下这个寄存器的位值说明:
上面的位值表示了模块在工作过程中的一些关键性的状态数据,包括:
数据是否已经发送成功/是否发送失败/是否收到了外界的新数据/新数据来自哪个pipe/数据缓冲区是否已被写满
我们的程序在运行时一定会非常频繁的要获知这些状态,【 状态字 】给我们提供了某种福利:
不需要专门使用【命令字(0x00+0x07=0x07)】去读取STATUS,任何一次与模块的交互过程都能立即得到STATUS的值。
当然你非要使用读寄存器的方式获取STATUS也是可以的,就是效率低一点儿。
【命令字】和【状态字】过后,从第二个字节开始,后面都是数据字节。而数据字节的流向就只是单向的了。
【命令字】按照【
数据流向
】划分的话,可以分为3类:
一类是 给nrf2401送数据 ,比如写寄存器/写入待发送数据;
一类是 从nrf2401里面拿数据 ,比如读寄存区/读出其他模块发来的数据;
最后一类是 没有数据 ,只有命令,比如FLUSH_TX/FLUSH_RX只是通知模块清空内部数据缓冲区,明显不需要提供数据。
不存在既要给模块送数据同时也要从模块里读出数据的情况,所以说 数据流向是单向的 。
对于R_REGISTER命令,数据从模块流出,于是有效数据在MISO这根线上,MOSI上的数据就无所谓了;
同理,对于W_REGISTER命令,数据从主机流入模块,有效数据在MOSI这根线上,MISO上有啥无所谓;
绝大部分命令只带一个字节的数据就行了,个别情况需要附带多个字节的数据,以W_REGISTER为例:
数据通道pipe0的地址最长5个字节,在nrf2401内部只给这个pipe0_adr寄存器分配了1个寄存器地址而不是5个。
这个寄存器地址是0x0A,所以我们可以认为0x0A是一个长度为5字节的寄存器。
假设我们要给pipe0设置的地址为: 0xA4A3A2A1A0,拆开看从高到低5字节:0xA4 0xA3 0xA2 0xA1 0xA0
前面说过,SPI传输时字节内部高位bit优先输出,而协议规定传输多字节数据时,【低字节优先】输出。
于是MOSI信号线上字节流的顺序是这样的: CMD-A0-A1-A2-A3-A4
最后,数据传输完毕,CSN要拉高,即代表模块的SPI断开了主机的连接,也让nrf2401知晓一条命令结束了。
这个地方必须提醒,CSN拉高是必须的,哪怕你有很多命令排队等着操作模块,每条命令的写入都要遵守: 【CSN拉低-数据传输-CSN拉高】这条规定。
啰嗦了一大堆话,一张图足以代表一切:
解读一下这张图对我们
写程序
有什么用:
模块要求MOSI/MISO在SCK上升沿的时候输出bit,不管是软件模拟SPI还是硬件SPI要特别注意这一点,尤其是stm32这类SOC当主控时,它的SPI功能非常繁多,
配置SPI工作模式
的时候要特别注意
两条操作命令之间要在CSN高电平时添加适当延时
上图红框标出的Tcwh,这个时间代表上一条命令结束后,下条命令开始前,必须要有个恢复时间,防止误动作。
这个时间不要少于【100纳秒】,保守起见,建议
至少延时【500纳秒】
。
关于SPI接口,最后再说一下SCK时钟频率的问题:
nrf2401模块的时钟频率最高可以到10MHz,但保守起见,我们实际使用是建议时钟速度不要超过8M, 留一些余量总是好的 。
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
CE 可以单独算一组,这个管脚和 nrf2401射频模块的工作状态 有关。
当nrf2401被配置成PTX时,我们通过SPI写入要对外发送的数据之后,模块并不会立即启动发送,
我们必须再拉高CE管脚并使其高电平保持至少10微秒(10微秒过后,可以拉低也可以继续保持高电平),
模块才会开启射频模块,进入【
发送状态
】,开始发送数据。
当nrf2401被配置成PRX时,同样模块也不会立即启动射频模块进入【接收状态】
,
我们必须拉高CE并使其一直保持高电平,模块才会进入【接收状态】开始监听数据。
任意时刻,只要CE被拉低了,PRX会立即从【接收状态】退出到待机状态。
这只是CE管脚的基本用处,更多的细节我们后面在讲完【发送/接收缓冲区】以及【工作状态图】之后再说。
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
三、IRQ
IRQ 也单独算一组,这个管脚如其名,是模块用来通知主机【
数据发送/数据接收相关的紧急事件
】的快捷通道。
相对于单片机的运行速度来说,nrf2401是比较慢的,8M的SPI时钟下,主机要对外发送32字节数据,
只需要不到40微秒就能将数据全部塞给模块,而模块想要将这些数据发送完毕,需要的时间却是要多得多。
主机当然可以在写完数据之后,一遍遍的询问模块数据是否发送完成,但同时主机也不可能去干别的事情了,所以必须要使用中断通知的方式来减轻主机的压力。
主机写完数据之后就可以去忙别的了,后续发送过程/成功确认/发送失败确认的一系列工作交给模块自主完成,一旦结果出来之后,模块立即将IRQ管脚拉低。
主机端一般会将自己的外部中断管脚和模块的IRQ管脚连在一起,一旦IRQ管脚被模块置为有效,主机端的外部中断会立即触发,然后就可以在中断函数中访问模块,查看发生了什么。
这中 紧急事件只有3种 : 【数据发送成功】/【数据发送失败且已经多次失败】/【收到其他模块发来的新数据】
当中任意一个单独发生或任意多个同时发生,都会触发IRQ,所以主机程序在获知中断发生之后,必须在读取一遍模块内部的STATUS寄存器才能准确知道是哪一种事件触发了IRQ。
关于IRQ更细致的问题,后面章节中在讨论。
举报
更多回帖
rotate(-90deg);
回复
相关问答
接口
模块
怎样使用STM32F407和
NRF2401
WIFI
模块
去完成
NRF2401
模块
的配置
呢
2021-12-16
1447
nrf2401
如何传输大量数据
2021-08-18
3794
请问
NRF2401
模块
如何抗干扰?
2020-04-22
1634
请问
NRF2401
最多能实现
一
点对多少点的通信?
2020-04-30
1716
WIFI无线
模块
有
哪几种
常用的通信
接口
?
2014-11-11
5725
关于
nrf2401
的供电问题如何解决
2020-05-26
558
NRF2401
丢包现象怎么解决?
2020-04-16
2638
nrf2401
芯片用单片机控制,若是用FPGA时序控制,注意哪些?
2015-03-12
2975
请问
NRF2401
掉电可否接收数据
2020-05-18
1125
请问
一下
STM32 定时器的脉冲计数
有
哪几种
方式
呢
2021-11-22
1782
发帖
登录/注册
20万+
工程师都在用,
免费
PCB检查工具
无需安装、支持浏览器和手机在线查看、实时共享
查看
点击登录
登录更多精彩功能!
首页
论坛版块
小组
免费开发板试用
ebook
直播
搜索
登录
×
20
完善资料,
赚取积分