本帖最后由 xiao_yp2014 于 2016-6-7 13:55 编辑
如何快速搞通“NRF24L01”,你造吗? http://www.51hei.com/bbs/dpj-51459-1.html
nRF24L01应用笔记(下)
上面一篇说了一下调试的方法和步骤,接下来说一下程序当中需要注意的地方。首先,不要把nRF24L01芯片想得太神秘,其实就是一个无线通信的芯片,通信的一些参数(通信速率,地址位长度,数据位长度)需要写内部寄存器来设置。单片机和芯片是用SPI通信,这个就不再说了,那么,就直接进入主题。
一、nRF24L01的寄存器 首先来了解一下寄存器(下面这些寄存器地址只是一个偏移地址)
- #define CONFIG 0x00 // 配置寄存器地址
- #define EN_AA 0x01 // 使能ACK自动应答功能地址
- #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接收地址,最大数据长度5个字节
- #define RX_ADDR_P1 0x0B // 数据通道1接收地址,最大数据长度5个字节
- #define RX_ADDR_P2 0x0C // 数据通道2接收地址,最低字节可设置,高字节部分必须与RX_ADDR相同
- #define RX_ADDR_P3 0x0D // 数据通道3接收地址,最低字节可设置,高字节部分必须与RX_ADDR相同
- #define RX_ADDR_P4 0x0E // 数据通道4接收地址,最低字节可设置,高字节部分必须与RX_ADDR相同
- #define RX_ADDR_P5 0x0F // 数据通道5接收地址,最低字节可设置,高字节部分必须与RX_ADDR相同
- #define TX_ADDR 0x10 // 发送地址,在增强型模式下,要与RX_ADDR_P0相同
- #define RX_PW_P0 0x11 // 接收数据通道0有效数据宽度(1~32个字节)
- #define RX_PW_P1 0x12 // 接收数据通道1有效数据宽度(1~32个字节)
- #define RX_PW_P2 0x13 // 接收数据通道2有效数据宽度(1~32个字节)
- #define RX_PW_P3 0x14 // 接收数据通道3有效数据宽度(1~32个字节)
- #define RX_PW_P4 0x15 // 接收数据通道4有效数据宽度(1~32个字节)
- #define RX_PW_P5 0x16 // 接收数据通道5有效数据宽度(1~32个字节)
- #define FIFO_STATUS 0x17 // FIFO状态寄存器地址
复制代码
上面一些寄存器地址并不是真实的地址,是一个偏移地址,那实际地址如何表示呢? 实际地址 = 基地址 + 偏移地址
二、nRF24L01操作命令(下面的操作命令就是基地址)
- #define READ_REG 0x00 // 读配置寄存器命令
- #define WRITE_REG 0x20 // 写配置寄存器命令
- #define RD_RX_PLOAD 0x61 // 读RX有效数据命令
- #define WR_TX_PLOAD 0xA0 // 写TX有效数据命令
- #define FLUSH_TX 0xE1 // 清除TX_FIFO寄存器,应用于发射模式
- #define FLUSH_RX 0xE2 // 清除RX_FIFO寄存器,应用于接收模式
- #define REUSE_TX_PL 0xE3 // 应用发射,重新发送上一包有效数据
- //#define NOP 0xFF // 空操作命令,一般没有使用
复制代码
上面一些寄存器地址并不是真实的地址,是一个偏移地址,那实际地址如何表示呢? 实际地址 = 基地址 + 偏移地址 在程序中就会有这样写,如下:
- SPI_Write_Reg(WRITE_REG + RX_PW_P0, TX_ADR_WIDTH); //接收数据通道0有效数据宽度5个字节
- WRITE_REG + RX_PW_P0就是设置接收数据宽度的实际寄存器
复制代码
三、nRF24L01初始化 初始化就是设置nRF24L01的默认工作状态,和发送或接收的一些要求,比如选择接收通道,速率,发射功率之类的东西,这些在网上都可以找到程序,我也就不多说了,只提一下需要注意的地方 SPI_Write_Reg(WRITE_REG + RF_CH, 40); // 选择射频通道0x40 这个是设置射频通道,后面的40可以随便定义使用,只要发送和接收一致就行了,我是这样处理的,可能还有其它的解释。
四、nRF24L01设置寄存器 寄存器设置和我们使用51单片机是一样的,都是写一些参数,来开启或关闭某一个功能,唯一不同一点是,51单片机的地址是定义好了的,只需要向里面写数据就可以了,但是nRF24L01不能这样做,因为它内部没有这个地址管理,就必须由主设备来选择地址,才可以对号入座,向规定的寄存器写正确的数据。 配置寄存器参数时,要先写地址,再写参数。
看看程序中是如何处理的 - SPI_Write_Reg(WRITE_REG + RX_PW_P0, TX_ADR_WIDTH); //这个是调用下面的函数
- unsigned char SPI_Write_Reg(unsigned char ucWrite_Reg, unsigned char ucWriteValue)
- {
- unsigned char ucStatus;
- CSN = 0; // CSN置低,开始传输数据
- ucStatus = SPI_Simulation(ucWrite_Reg); // 选择寄存器,同时返回状态字
- SPI_Simulation(ucWriteValue); // 然后写数据到该寄存器
- CSN = 1; // CSN拉高,结束数据传输
- return(ucStatus); // 返回状态寄存器
- }
复制代码
红色是地址 蓝色是数据
五、nRF24L01的查询方法(中断查询和状态寄存器查询,主要介绍状态寄存器查询方法)
nRF24L01的查询方法有两种: 1、中断查询
IRQ:中断信号。无线通信过程中 MCU 主要是通过 IRQ 与 NRF24L01 进行通信。 中断查询开启后,当接收成功或者发送成功在中断引脚上面会有一个低电平,把IRQ引脚接在单片机的外部中断引脚上面,就能够实时查询。
2、状态寄存器查询 状态寄存器查询:就是通过软件查询这个寄存器的置位或者是清零,来判断是发送成功还是接收成功。
状态寄存器查询程序如下:
- unsigned char bdata StateFalg;//状态标志位,定义在bdata ,是可以位寻址。
- sbit RX_DR = StateFalg^6; //接收中断标志位
- sbit TX_DS = StateFalg^5; //发送中断标志位
- sbit MAX_RT = StateFalg^4; //发送次数超过10次中断标志位
- StateFalg = SPI_Read_Reg(READ_REG+STATUS); // 返回状态寄存器
- SPI_Write_Reg(WRITE_REG+STATUS,StateFalg); // 清零对应中断标志
- if(RX_DR == 1)
- {
- SPI_Read_Buf(RD_RX_PLOAD,RX_BUF, TX_PLOAD_WIDTH); //从FIFO缓存中读取数据,存入数组。
- SPI_Write_Reg(FLUSH_RX,0); //清除RX_FIFO寄存器
- }
复制代码
六、接收或发送模式的切换
最后说一下模式的切换,模式切换可以在CONFIG寄存器中找到,先看一下 CONFIG的定义。
位7:RESERVED 默认为“0”
位6:MASK_RX_DR 可屏蔽中断RX_DR 1:IRQ引脚不产生RX_DR 中断 0:RX_DR 中断产生时IRQ引脚为低电平
位5:MASK_TX_DS 可屏蔽中断TX_DR 1:IRQ引脚不产生TX_DR 中断 0:TX_DR 中断产生时IRQ引脚为低电平
位4:MASK_MAX_RT 可屏蔽中断MAX_RT 1:IRQ引脚不产生TX_DS中断 0:MAX_RT中断产生时,IRQ引脚为低电平
位3:EN_CRC CRC使能端 如果EN_AA中任意一位为高,则EN_CRC强迫为高
位2:CRCO CRC模式 1:16位CRC校验 0:8位CRC校验
位1: PWR_UP 芯片模式设置 1:上电模式 0:掉电模式
位0: PRIM_RX 接收或发射模式 1:接收模式 0:发射模式
在程序中只需要对相应的位置“0”或者置“1”,程序如下
- 接收模式:
- SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); //接收地址宽度
- SPI_Write_Reg(WRITE_REG+RX_PW_P0,TX_PLOAD_WIDTH); // 接收数据长度
- SPI_Write_Reg(WRITE_REG+CONFIG,0x0f); // 接收模式,8CRC校验,IRQ中断显示,上电发送
- 发送模式:
- SPI_Write_Buf(TX_ADDR, ucTX_Address, TX_ADR_WIDTH); // 写入发送地址
- SPI_Write_Buf(WR_TX_PLOAD, ucTxData, TX_PLOAD_WIDTH); //装载数据到FIFO中
- SPI_Write_Reg(WRITE_REG+CONFIG,0x0e); // 发送模式,8CRC校验,IRQ中断显示,上电发送
复制代码
到这里,nRF24L01无线芯片的一些基本操作和注意事项就是这样。
|