/**********************************************************************
宏定义
***********************************************************************/
//==========================NRF24L01============================================
#define RX_MULIT_CHANNEL 1 //【0:单通道(默认通道0)】【1:多通道(6通道全开)】
#define DYNAMIC_PLOAD_LENGTH 1 //【0:固定数据长度】【1:动态数据长度】
#define STATIC_PLOAD_LENGTH 5 //设置数据长度(固定数据长度下使用)
#define ADDRESS_WIDTH 5 //通道地址宽度
//#define TX_ADR_WIDTH 5 //发送端的接收通道地址宽度
//#define RX_ADR_WIDTH 5 //接收端的接收通道地址宽度
//#define TX_PLOAD_WIDTH 5 //要发送的有效数据长度(固定长度)
//#define RX_PLOAD_WIDTH 5 //要接收的有效数据长度(固定长度),这个决定RX端FIFO达到多少数据量后触发中断
//------------------------RX通道地址【低字节在前!!!】-----------------------------------------------------------------------
extern u8 RX_ADDRESS_0[ADDRESS_WIDTH];
extern u8 RX_ADDRESS_1[ADDRESS_WIDTH];
extern u8 RX_ADDRESS_2[ADDRESS_WIDTH];
extern u8 RX_ADDRESS_3[ADDRESS_WIDTH];
extern u8 RX_ADDRESS_4[ADDRESS_WIDTH];
extern u8 RX_ADDRESS_5[ADDRESS_WIDTH];
//=========================NRF24L01寄存器指令===================================
#define R_REGISTER 0x00 // 读寄存器指令
#define W_REGISTER 0x20 // 写寄存器指令
#define RD_RX_PLOAD 0x61 // 读取接收数据指令(PTX.PRX)
#define WR_TX_PLOAD 0xA0 // 写待发数据指令(PTX)
#define FLUSH_TX 0xE1 // 清空TX_FIFO内的数据指令(PTX.PRX)
#define FLUSH_RX 0xE2 // 清空RX_FIFO内的数据指令(PTX.PRX)
#define REUSE_TX_PL 0xE3 // 定义重复装载数据指令(PTX)
#define R_RX_PL_WID 0x60 // 接收到的有效数据宽度
//#define W_ACK_PAYLOAD 0x?? // 没用到
//#define W_TX_PAYLOAD_NO_ACK 0xA0 // 没用到
#define NOP 0xFF // 保留
//========================SPI(nRF24L01)寄存器地址===============================
#define CONFIG 0x00 // 配置收发状态,CRC校验模式以及收发状态响应方式
#define EN_AA 0x01 // 自动应答功能设置
#define EN_RXADDR 0x02 // 可用信道设置
#define SETUP_AW 0x03 // 收发地址宽度设置
#define SETUP_RETR 0x04 // 自动重发功能设置
#define RF_CH 0x05 // 工作频率设置
#define RF_SETUP 0x06 // 发射速率、功耗功能设置
#define STATUS 0x07 // 状态寄存器
#define OBSERVE_TX 0x08 // 发送监测功能
#define CD 0x09 // 地址检测
#define RX_ADDR_P0 0x0A // 频道0接收数据地址
#define RX_ADDR_P1 0x0B // 频道1接收数据地址
#define RX_ADDR_P2 0x0C // 频道2接收数据地址
#define RX_ADDR_P3 0x0D // 频道3接收数据地址
#define RX_ADDR_P4 0x0E // 频道4接收数据地址
#define RX_ADDR_P5 0x0F // 频道5接收数据地址
#define TX_ADDR 0x10 // 发送地址寄存器
#define RX_PW_P0 0x11 // 接收频道0接收数据长度
#define RX_PW_P1 0x12 // 接收频道0接收数据长度
#define RX_PW_P2 0x13 // 接收频道0接收数据长度
#define RX_PW_P3 0x14 // 接收频道0接收数据长度
#define RX_PW_P4 0x15 // 接收频道0接收数据长度
#define RX_PW_P5 0x16 // 接收频道0接收数据长度
#define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器
#define DYNPD 0x1C // 动态有效数据长度寄存器
#define FEATURE 0x1D // 与动态有效数据长度相关
//=============================RF24l01状态=====================================
//CONFIG寄存器
#define PWR_UP 0x02 //Power Up
#define PWR_DOWN 0x00 //Power Down
#define PRIM_RX 0x01 //PRX
#define PRIM_TX 0x00 //PTX
//发生中断时,根据STATUS寄存器中的值来判断是哪个中断源触发了IRQ中断
#define IRQ_STATUS 0x70 //提取中断标志位
#define IRQ_CLEAR 0x7E //清除中断标志位
#define RX_DR 0x40 //数据接收完成中断
#define TX_DS 0x20 //数据发送完成中断
#define MAX_RT 0x10 //数据包重发次数超过设定值中断
//nRF配置
void NRF_SPI_Config(void); //nRF的SPI及CE CSN IRQ接口配置
void NRF_Config(void); //nRF初始化
u8 NRF_Check(void); //检查MCU和nRF的连接
//-----------------------------------------------------------
//nRF寄存器读写 调用以下API均会刷新status的值
u8 NRF_SPI_ReadReg(u8 reg);
u8 NRF_SPI_ReadBuf(u8 reg,u8 *buf,u8 len);
u8 NRF_SPI_WriteReg(u8 reg,u8 dat);
u8 NRF_SPI_WriteBuf(u8 reg ,u8 *buf,u8 len);
//-----------------------------------------------------------
//-----------------------------------------------------------
//先调用【NRF_CE_LOW;】拉低进入待机模式或掉电模式
//再调用以下API
void NRF_RX_Mode(void); //配置成PRX
void NRF_TX_Mode(void); //配置成PTX
//-----------------------------------------------------------
//nRF_API
void NRF_ReceivePacket(void);
void NRF_SendPacket(u8 *RX_ADDRESS_X,u8 *TX_BUFF); //发送固定长度有效数据包
void NRF_SendPacket_DPL(u8 *RX_ADDRESS_X,u8 * TX_BUFF, u32 length); //发送动态长度有效数据包
#endif /* __NRF_H */
对于
#include "bsp_conf.h"
这是包含了我工程的所有BSP头文件,但这里只用到了【delay.h】你们可用直接替换成自己的延时文件
底层链接和SPI链接前面讲过了,不再累述
通道地址是在多通道模式下发送数据时外部会调用到的,这里设置为extern,后面会讲解
接下来就是NRF的操作指令,对应的值都是可以在数据手册里第51页8.3.1章节里得到

【PTX:主发射模式】【PRX:主接收模式】
括号里面的表示该指令在那种模式下会用到
操作指令分为两种【只需操作指令】【操作指令+地址信息】
在前面的【void NRF_Check(void)】函数里就调用了一句
NRF_SPI_WriteBuf(W_REGISTER+TX_ADDR,buf,5);
这就是第二种操作指令,写指令【W_REGISTER】+寄存器地址【TX_ADDR】
length = NRF_SPI_ReadReg(R_RX_PL_WID);
上面这类型就是第一种操作指令,只需要写入指令【R_RX_PL_WID】就能得到数据
代码接下来的就是寄存器地址了,同样可以在数据手册9.1章节可以查到
常用寄存器功能
CONFIG
芯片的三种中断 【使能/失能】
CRC校验 【使能/失能】
CRC位数 【1byte/2byte】
芯片进入 【掉电模式/上电模式】
芯片进入 【发射模式/接收模式】
EN_AA
【使能/失能】通道0~5的自动应答功能
EN_RXADDR
【使能/失能】通道0~5接收通道,使其在PRX模式下能够接收数据
SETUP_AW
设置地址宽度,常用的是5byte长度,也就是前面见到的
u8 RX_ADDRESS_0[ADDRESS_WIDTH];
这些地址数组的长度【ADDRESS_WIDTH】
SETUP_RETR
设置超时自动重发的时间和重发次数,具体看数据手册解释
RF_CH
设置使用的通信频段
RF_SETUP
设置射频通信速率和功率等
STATUS
这是前面提到过的一个很重要的寄存器
bit 说明
7 保留,必须为0
6 RX_DR 接收标志位,当接收到有效数据时置1
5 TX_DS 发送标志位,当发送成功时置1
4 MAX_RT 超时标志位,当重发超过设定次数时置1
以上三位任何一种情况都会触发IRQ
3:1 RX_P_NO 可以判断接收到的数据通道是来自哪个通道的
000~101,对应的通道
0 TX_FULL 判断TX_FIFO是否装满
注意 当时间成功发送出去,TX_FIFO会自动清空
在发送超时的情况下,TX_FIFO不会自动清空,当TX_FIFO填满,就不用能再发送数据给TX_FIFO了,必须清空
RX_ADDR_P0
RX_ADDR_P1
RX_ADDR_P2
RX_ADDR_P3
RX_ADDR_P4
RX_ADDR_P5
这六个寄存器是用来【存放】接收通道地址的,也就是前面提到的六个地址
//------------------------RX通道地址【低字节在前!!!】---------------------------------
u8 RX_ADDRESS_0[ADDRESS_WIDTH] = {0x00,0x34,0x22,0x1D,0x10}; //NRF的RX0通道的地址
u8 RX_ADDRESS_1[ADDRESS_WIDTH] = {0x01,0x34,0x22,0x1D,0x10}; //NRF的RX1通道的地址
u8 RX_ADDRESS_2[ADDRESS_WIDTH] = {0x02,0x34,0x22,0x1D,0x10}; //NRF的RX2通道的地址
u8 RX_ADDRESS_3[ADDRESS_WIDTH] = {0x03,0x34,0x22,0x1D,0x10}; //NRF的RX3通道的地址
u8 RX_ADDRESS_4[ADDRESS_WIDTH] = {0x04,0x34,0x22,0x1D,0x10}; //NRF的RX4通道的地址
u8 RX_ADDRESS_5[ADDRESS_WIDTH] = {0x05,0x34,0x22,0x1D,0x10}; //NRF的RX5通道的地址
在数据手册7.6章节里说明
通道0和通道1的值是任意的,但是不能相同
通道2~5和通道1共用高4位,最低1位必须不同,不然是接收不到数据的
而且是低字节在前!!!本人一开始设置的地址是高字节在在前,导致通道0和通道1都能通信,一切换到通道2~5就没有任何反应了
TX_ADDR
用来存放发送通道地址
RX_PW_P0
RX_PW_P1
RX_PW_P2
RX_PW_P3
RX_PW_P4
RX_PW_P5
这是配置每个通道的一次接收有效数据长度,最大值为32byte
当该通道接收到的数据等于设定的值,就会触发IRQ中断
FIFO_STATUS
存放TX_FIFO和RX_FIFO相关状态的寄存器,详见数据手册
DYNPD
【使能/失能】各个通道的动态数据接收功能
FEATURE
配合动态数据长度功能使用,开启动态数据长度自动应答功能等,详见数据手册
上面就是对常用的寄存器的功能解释,没有讲到的寄存器可以看数据手册
只要在正确时刻正确配置好以上的寄存器,就能顺利使用NRF模块的所有通道、动态数据长度等功能,
nRF初始化
这里正式开始对nRF模块进行初始化配置
首先要数据手册6.1.1章节对于芯片的运行流程解释,不清晰的话还请看数据手册里的,这个流程图告诉了我们应该如何配置才能正常使用芯片

首先是芯片上电,1m后处于默认掉电模式,也可以理解为低功耗模式,当PWR_UP = 1的时候,进入standby-1模式,也就是待机模式
在待机模式下,若PRIM_RX = 1且CE = 1,会进入接收模式,接收数据
在待机模式下,若PRIM_RX = 0且CE = 1且TX_FIFO非空,会进入发射模式,发送数据
对这张图更详细的解释可以看其他博主的文章【NRF】
/**********************************************************************
宏定义
***********************************************************************/
//==========================NRF24L01============================================
#define RX_MULIT_CHANNEL 1 //【0:单通道(默认通道0)】【1:多通道(6通道全开)】
#define DYNAMIC_PLOAD_LENGTH 1 //【0:固定数据长度】【1:动态数据长度】
#define STATIC_PLOAD_LENGTH 5 //设置数据长度(固定数据长度下使用)
#define ADDRESS_WIDTH 5 //通道地址宽度
//#define TX_ADR_WIDTH 5 //发送端的接收通道地址宽度
//#define RX_ADR_WIDTH 5 //接收端的接收通道地址宽度
//#define TX_PLOAD_WIDTH 5 //要发送的有效数据长度(固定长度)
//#define RX_PLOAD_WIDTH 5 //要接收的有效数据长度(固定长度),这个决定RX端FIFO达到多少数据量后触发中断
//------------------------RX通道地址【低字节在前!!!】-----------------------------------------------------------------------
extern u8 RX_ADDRESS_0[ADDRESS_WIDTH];
extern u8 RX_ADDRESS_1[ADDRESS_WIDTH];
extern u8 RX_ADDRESS_2[ADDRESS_WIDTH];
extern u8 RX_ADDRESS_3[ADDRESS_WIDTH];
extern u8 RX_ADDRESS_4[ADDRESS_WIDTH];
extern u8 RX_ADDRESS_5[ADDRESS_WIDTH];
//=========================NRF24L01寄存器指令===================================
#define R_REGISTER 0x00 // 读寄存器指令
#define W_REGISTER 0x20 // 写寄存器指令
#define RD_RX_PLOAD 0x61 // 读取接收数据指令(PTX.PRX)
#define WR_TX_PLOAD 0xA0 // 写待发数据指令(PTX)
#define FLUSH_TX 0xE1 // 清空TX_FIFO内的数据指令(PTX.PRX)
#define FLUSH_RX 0xE2 // 清空RX_FIFO内的数据指令(PTX.PRX)
#define REUSE_TX_PL 0xE3 // 定义重复装载数据指令(PTX)
#define R_RX_PL_WID 0x60 // 接收到的有效数据宽度
//#define W_ACK_PAYLOAD 0x?? // 没用到
//#define W_TX_PAYLOAD_NO_ACK 0xA0 // 没用到
#define NOP 0xFF // 保留
//========================SPI(nRF24L01)寄存器地址===============================
#define CONFIG 0x00 // 配置收发状态,CRC校验模式以及收发状态响应方式
#define EN_AA 0x01 // 自动应答功能设置
#define EN_RXADDR 0x02 // 可用信道设置
#define SETUP_AW 0x03 // 收发地址宽度设置
#define SETUP_RETR 0x04 // 自动重发功能设置
#define RF_CH 0x05 // 工作频率设置
#define RF_SETUP 0x06 // 发射速率、功耗功能设置
#define STATUS 0x07 // 状态寄存器
#define OBSERVE_TX 0x08 // 发送监测功能
#define CD 0x09 // 地址检测
#define RX_ADDR_P0 0x0A // 频道0接收数据地址
#define RX_ADDR_P1 0x0B // 频道1接收数据地址
#define RX_ADDR_P2 0x0C // 频道2接收数据地址
#define RX_ADDR_P3 0x0D // 频道3接收数据地址
#define RX_ADDR_P4 0x0E // 频道4接收数据地址
#define RX_ADDR_P5 0x0F // 频道5接收数据地址
#define TX_ADDR 0x10 // 发送地址寄存器
#define RX_PW_P0 0x11 // 接收频道0接收数据长度
#define RX_PW_P1 0x12 // 接收频道0接收数据长度
#define RX_PW_P2 0x13 // 接收频道0接收数据长度
#define RX_PW_P3 0x14 // 接收频道0接收数据长度
#define RX_PW_P4 0x15 // 接收频道0接收数据长度
#define RX_PW_P5 0x16 // 接收频道0接收数据长度
#define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器
#define DYNPD 0x1C // 动态有效数据长度寄存器
#define FEATURE 0x1D // 与动态有效数据长度相关
//=============================RF24l01状态=====================================
//CONFIG寄存器
#define PWR_UP 0x02 //Power Up
#define PWR_DOWN 0x00 //Power Down
#define PRIM_RX 0x01 //PRX
#define PRIM_TX 0x00 //PTX
//发生中断时,根据STATUS寄存器中的值来判断是哪个中断源触发了IRQ中断
#define IRQ_STATUS 0x70 //提取中断标志位
#define IRQ_CLEAR 0x7E //清除中断标志位
#define RX_DR 0x40 //数据接收完成中断
#define TX_DS 0x20 //数据发送完成中断
#define MAX_RT 0x10 //数据包重发次数超过设定值中断
//nRF配置
void NRF_SPI_Config(void); //nRF的SPI及CE CSN IRQ接口配置
void NRF_Config(void); //nRF初始化
u8 NRF_Check(void); //检查MCU和nRF的连接
//-----------------------------------------------------------
//nRF寄存器读写 调用以下API均会刷新status的值
u8 NRF_SPI_ReadReg(u8 reg);
u8 NRF_SPI_ReadBuf(u8 reg,u8 *buf,u8 len);
u8 NRF_SPI_WriteReg(u8 reg,u8 dat);
u8 NRF_SPI_WriteBuf(u8 reg ,u8 *buf,u8 len);
//-----------------------------------------------------------
//-----------------------------------------------------------
//先调用【NRF_CE_LOW;】拉低进入待机模式或掉电模式
//再调用以下API
void NRF_RX_Mode(void); //配置成PRX
void NRF_TX_Mode(void); //配置成PTX
//-----------------------------------------------------------
//nRF_API
void NRF_ReceivePacket(void);
void NRF_SendPacket(u8 *RX_ADDRESS_X,u8 *TX_BUFF); //发送固定长度有效数据包
void NRF_SendPacket_DPL(u8 *RX_ADDRESS_X,u8 * TX_BUFF, u32 length); //发送动态长度有效数据包
#endif /* __NRF_H */
对于
#include "bsp_conf.h"
这是包含了我工程的所有BSP头文件,但这里只用到了【delay.h】你们可用直接替换成自己的延时文件
底层链接和SPI链接前面讲过了,不再累述
通道地址是在多通道模式下发送数据时外部会调用到的,这里设置为extern,后面会讲解
接下来就是NRF的操作指令,对应的值都是可以在数据手册里第51页8.3.1章节里得到

【PTX:主发射模式】【PRX:主接收模式】
括号里面的表示该指令在那种模式下会用到
操作指令分为两种【只需操作指令】【操作指令+地址信息】
在前面的【void NRF_Check(void)】函数里就调用了一句
NRF_SPI_WriteBuf(W_REGISTER+TX_ADDR,buf,5);
这就是第二种操作指令,写指令【W_REGISTER】+寄存器地址【TX_ADDR】
length = NRF_SPI_ReadReg(R_RX_PL_WID);
上面这类型就是第一种操作指令,只需要写入指令【R_RX_PL_WID】就能得到数据
代码接下来的就是寄存器地址了,同样可以在数据手册9.1章节可以查到
常用寄存器功能
CONFIG
芯片的三种中断 【使能/失能】
CRC校验 【使能/失能】
CRC位数 【1byte/2byte】
芯片进入 【掉电模式/上电模式】
芯片进入 【发射模式/接收模式】
EN_AA
【使能/失能】通道0~5的自动应答功能
EN_RXADDR
【使能/失能】通道0~5接收通道,使其在PRX模式下能够接收数据
SETUP_AW
设置地址宽度,常用的是5byte长度,也就是前面见到的
u8 RX_ADDRESS_0[ADDRESS_WIDTH];
这些地址数组的长度【ADDRESS_WIDTH】
SETUP_RETR
设置超时自动重发的时间和重发次数,具体看数据手册解释
RF_CH
设置使用的通信频段
RF_SETUP
设置射频通信速率和功率等
STATUS
这是前面提到过的一个很重要的寄存器
bit 说明
7 保留,必须为0
6 RX_DR 接收标志位,当接收到有效数据时置1
5 TX_DS 发送标志位,当发送成功时置1
4 MAX_RT 超时标志位,当重发超过设定次数时置1
以上三位任何一种情况都会触发IRQ
3:1 RX_P_NO 可以判断接收到的数据通道是来自哪个通道的
000~101,对应的通道
0 TX_FULL 判断TX_FIFO是否装满
注意 当时间成功发送出去,TX_FIFO会自动清空
在发送超时的情况下,TX_FIFO不会自动清空,当TX_FIFO填满,就不用能再发送数据给TX_FIFO了,必须清空
RX_ADDR_P0
RX_ADDR_P1
RX_ADDR_P2
RX_ADDR_P3
RX_ADDR_P4
RX_ADDR_P5
这六个寄存器是用来【存放】接收通道地址的,也就是前面提到的六个地址
//------------------------RX通道地址【低字节在前!!!】---------------------------------
u8 RX_ADDRESS_0[ADDRESS_WIDTH] = {0x00,0x34,0x22,0x1D,0x10}; //NRF的RX0通道的地址
u8 RX_ADDRESS_1[ADDRESS_WIDTH] = {0x01,0x34,0x22,0x1D,0x10}; //NRF的RX1通道的地址
u8 RX_ADDRESS_2[ADDRESS_WIDTH] = {0x02,0x34,0x22,0x1D,0x10}; //NRF的RX2通道的地址
u8 RX_ADDRESS_3[ADDRESS_WIDTH] = {0x03,0x34,0x22,0x1D,0x10}; //NRF的RX3通道的地址
u8 RX_ADDRESS_4[ADDRESS_WIDTH] = {0x04,0x34,0x22,0x1D,0x10}; //NRF的RX4通道的地址
u8 RX_ADDRESS_5[ADDRESS_WIDTH] = {0x05,0x34,0x22,0x1D,0x10}; //NRF的RX5通道的地址
在数据手册7.6章节里说明
通道0和通道1的值是任意的,但是不能相同
通道2~5和通道1共用高4位,最低1位必须不同,不然是接收不到数据的
而且是低字节在前!!!本人一开始设置的地址是高字节在在前,导致通道0和通道1都能通信,一切换到通道2~5就没有任何反应了
TX_ADDR
用来存放发送通道地址
RX_PW_P0
RX_PW_P1
RX_PW_P2
RX_PW_P3
RX_PW_P4
RX_PW_P5
这是配置每个通道的一次接收有效数据长度,最大值为32byte
当该通道接收到的数据等于设定的值,就会触发IRQ中断
FIFO_STATUS
存放TX_FIFO和RX_FIFO相关状态的寄存器,详见数据手册
DYNPD
【使能/失能】各个通道的动态数据接收功能
FEATURE
配合动态数据长度功能使用,开启动态数据长度自动应答功能等,详见数据手册
上面就是对常用的寄存器的功能解释,没有讲到的寄存器可以看数据手册
只要在正确时刻正确配置好以上的寄存器,就能顺利使用NRF模块的所有通道、动态数据长度等功能,
nRF初始化
这里正式开始对nRF模块进行初始化配置
首先要数据手册6.1.1章节对于芯片的运行流程解释,不清晰的话还请看数据手册里的,这个流程图告诉了我们应该如何配置才能正常使用芯片

首先是芯片上电,1m后处于默认掉电模式,也可以理解为低功耗模式,当PWR_UP = 1的时候,进入standby-1模式,也就是待机模式
在待机模式下,若PRIM_RX = 1且CE = 1,会进入接收模式,接收数据
在待机模式下,若PRIM_RX = 0且CE = 1且TX_FIFO非空,会进入发射模式,发送数据
对这张图更详细的解释可以看其他博主的文章【NRF】
举报