找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5256|回复: 1
打印 上一主题 下一主题
收起左侧

nRF24L01应用笔记(下)

[复制链接]
跳转到指定楼层
楼主
ID:69862 发表于 2015-7-24 22:44 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 xiao_yp2014 于 2016-6-7 13:55 编辑

上接:nRF24L01应用笔记(上)        http://www.51hei.com/bbs/dpj-37580-1.html
如何快速搞通“NRF24L01”,你造吗? http://www.51hei.com/bbs/dpj-51459-1.html





nRF24L01应用笔记(下)

上面一篇说了一下调试的方法和步骤,接下来说一下程序当中需要注意的地方。首先,不要把nRF24L01芯片想得太神秘,其实就是一个无线通信的芯片,通信的一些参数(通信速率,地址位长度,数据位长度)需要写内部寄存器来设置。单片机和芯片是用SPI通信,这个就不再说了,那么,就直接进入主题。

一、nRF24L01的寄存器
首先来了解一下寄存器(下面这些寄存器地址只是一个偏移地址)

  1. #define CONFIG      0x00  // 配置寄存器地址
  2. #define EN_AA       0x01  // 使能ACK自动应答功能地址
  3. #define EN_RXADDR   0x02  // 接收地址允许地址
  4. #define SETUP_AW    0x03  // 设置地址宽度地址
  5. #define SETUP_RETR  0x04  // 建立自动应答的时间地址
  6. #define RF_CH       0x05  // 射频通道地址
  7. #define RF_SETUP    0x06  // 射频寄存器地址
  8. #define STATUS      0x07  // 状态寄存器地址
  9. #define OBSERVE_TX  0x08  // 发送检测寄存器地址
  10. #define CD          0x09  // 载波检测地址
  11. #define RX_ADDR_P0  0x0A  // 数据通道0接收地址,最大数据长度5个字节
  12. #define RX_ADDR_P1  0x0B  // 数据通道1接收地址,最大数据长度5个字节
  13. #define RX_ADDR_P2  0x0C  // 数据通道2接收地址,最低字节可设置,高字节部分必须与RX_ADDR相同
  14. #define RX_ADDR_P3  0x0D  // 数据通道3接收地址,最低字节可设置,高字节部分必须与RX_ADDR相同
  15. #define RX_ADDR_P4  0x0E  // 数据通道4接收地址,最低字节可设置,高字节部分必须与RX_ADDR相同
  16. #define RX_ADDR_P5  0x0F  // 数据通道5接收地址,最低字节可设置,高字节部分必须与RX_ADDR相同
  17. #define TX_ADDR     0x10  // 发送地址,在增强型模式下,要与RX_ADDR_P0相同
  18. #define RX_PW_P0    0x11  // 接收数据通道0有效数据宽度(1~32个字节)
  19. #define RX_PW_P1    0x12  // 接收数据通道1有效数据宽度(1~32个字节)
  20. #define RX_PW_P2    0x13  // 接收数据通道2有效数据宽度(1~32个字节)
  21. #define RX_PW_P3    0x14  // 接收数据通道3有效数据宽度(1~32个字节)
  22. #define RX_PW_P4    0x15  // 接收数据通道4有效数据宽度(1~32个字节)
  23. #define RX_PW_P5    0x16  // 接收数据通道5有效数据宽度(1~32个字节)
  24. #define FIFO_STATUS 0x17  // FIFO状态寄存器地址
复制代码



上面一些寄存器地址并不是真实的地址,是一个偏移地址,那实际地址如何表示呢?
实际地址 = 基地址 + 偏移地址


二、nRF24L01操作命令(下面的操作命令就是基地址)

  1.         #define READ_REG    0x00  // 读配置寄存器命令
  2. #define WRITE_REG   0x20  // 写配置寄存器命令
  3. #define RD_RX_PLOAD 0x61  // 读RX有效数据命令
  4. #define WR_TX_PLOAD 0xA0  // 写TX有效数据命令
  5. #define FLUSH_TX    0xE1  // 清除TX_FIFO寄存器,应用于发射模式
  6. #define FLUSH_RX    0xE2  // 清除RX_FIFO寄存器,应用于接收模式
  7. #define REUSE_TX_PL 0xE3  // 应用发射,重新发送上一包有效数据
  8. //#define NOP         0xFF  // 空操作命令,一般没有使用
复制代码



  上面一些寄存器地址并不是真实的地址,是一个偏移地址,那实际地址如何表示呢?
实际地址 = 基地址 + 偏移地址
在程序中就会有这样写,如下:

  1.         SPI_Write_Reg(WRITE_REG + RX_PW_P0, TX_ADR_WIDTH);          //接收数据通道0有效数据宽度5个字节
  2.     WRITE_REG + RX_PW_P0就是设置接收数据宽度的实际寄存器
复制代码



三、nRF24L01初始化
初始化就是设置nRF24L01的默认工作状态,和发送或接收的一些要求,比如选择接收通道,速率,发射功率之类的东西,这些在网上都可以找到程序,我也就不多说了,只提一下需要注意的地方
SPI_Write_Reg(WRITE_REG + RF_CH, 40);       // 选择射频通道0x40
这个是设置射频通道,后面的40可以随便定义使用,只要发送和接收一致就行了,我是这样处理的,可能还有其它的解释。





四、nRF24L01设置寄存器
寄存器设置和我们使用51单片机是一样的,都是写一些参数,来开启或关闭某一个功能,唯一不同一点是,51单片机的地址是定义好了的,只需要向里面写数据就可以了,但是nRF24L01不能这样做,因为它内部没有这个地址管理,就必须由主设备来选择地址,才可以对号入座,向规定的寄存器写正确的数据。
配置寄存器参数时,要先写地址,再写参数。










    看看程序中是如何处理的
  1. SPI_Write_Reg(WRITE_REG + RX_PW_P0, TX_ADR_WIDTH);        //这个是调用下面的函数  

  2. unsigned char SPI_Write_Reg(unsigned char ucWrite_Reg, unsigned char ucWriteValue)
  3. {
  4.      unsigned char  ucStatus;
  5.      CSN = 0;                   // CSN置低,开始传输数据
  6.      ucStatus = SPI_Simulation(ucWrite_Reg); // 选择寄存器,同时返回状态字
  7.      SPI_Simulation(ucWriteValue);             // 然后写数据到该寄存器
  8.      CSN = 1;                   // CSN拉高,结束数据传输
  9.      return(ucStatus);            // 返回状态寄存器
  10. }
复制代码



红色是地址              
蓝色是数据





五、nRF24L01的查询方法(中断查询和状态寄存器查询,主要介绍状态寄存器查询方法)

nRF24L01的查询方法有两种:
1、中断查询

   IRQ:中断信号。无线通信过程中 MCU 主要是通过 IRQ 与 NRF24L01 进行通信。
   中断查询开启后,当接收成功或者发送成功在中断引脚上面会有一个低电平,把IRQ引脚接在单片机的外部中断引脚上面,就能够实时查询。



2、状态寄存器查询
   状态寄存器查询:就是通过软件查询这个寄存器的置位或者是清零,来判断是发送成功还是接收成功。




状态寄存器查询程序如下:

  1. unsigned char bdata StateFalg;//状态标志位,定义在bdata ,是可以位寻址。
  2. sbit RX_DR = StateFalg^6;        //接收中断标志位
  3. sbit TX_DS = StateFalg^5;        //发送中断标志位
  4. sbit MAX_RT = StateFalg^4;        //发送次数超过10次中断标志位

  5. StateFalg = SPI_Read_Reg(READ_REG+STATUS);  // 返回状态寄存器
  6. SPI_Write_Reg(WRITE_REG+STATUS,StateFalg);  // 清零对应中断标志

  7. if(RX_DR == 1)
  8. {
  9.       SPI_Read_Buf(RD_RX_PLOAD,RX_BUF, TX_PLOAD_WIDTH); //从FIFO缓存中读取数据,存入数组。
  10.       SPI_Write_Reg(FLUSH_RX,0);         //清除RX_FIFO寄存器
  11.         }
复制代码





六、接收或发送模式的切换



        最后说一下模式的切换,模式切换可以在CONFIG寄存器中找到,先看一下
        CONFIG的定义。
7
6
5
4
RESERVED
MASK_RX_DR
MASK_TX_DS
MASK_MAX_RT
3
2
1
0
EN_CRC
CRCO
PWR_UP
PRIM_RX



7RESERVED
     默认为“0

6MASK_RX_DR  可屏蔽中断RX_DR
     1IRQ引脚不产生RX_DR 中断
     0RX_DR 中断产生时IRQ引脚为低电平

5MASK_TX_DS  可屏蔽中断TX_DR
     1IRQ引脚不产生TX_DR 中断
     0TX_DR 中断产生时IRQ引脚为低电平

4MASK_MAX_RT  可屏蔽中断MAX_RT
     1IRQ引脚不产生TX_DS中断
     0MAX_RT中断产生时,IRQ引脚为低电平

3EN_CRC  CRC使能端
     如果EN_AA中任意一位为高,则EN_CRC强迫为高

2CRCO  CRC模式
     116CRC校验
     08CRC校验

1PWR_UP  芯片模式设置
     1:上电模式
     0:掉电模式

0PRIM_RX  接收或发射模式     
     1:接收模式
     0:发射模式

在程序中只需要对相应的位置“0”或者置“1”,程序如下

  1. 接收模式:

  2.         SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);   //接收地址宽度
  3.         SPI_Write_Reg(WRITE_REG+RX_PW_P0,TX_PLOAD_WIDTH);                                  // 接收数据长度
  4.         SPI_Write_Reg(WRITE_REG+CONFIG,0x0f);  // 接收模式,8CRC校验,IRQ中断显示,上电发送

  5. 发送模式:
  6.         SPI_Write_Buf(TX_ADDR, ucTX_Address, TX_ADR_WIDTH);     // 写入发送地址
  7.         SPI_Write_Buf(WR_TX_PLOAD, ucTxData, TX_PLOAD_WIDTH); //装载数据到FIFO中
  8.          SPI_Write_Reg(WRITE_REG+CONFIG,0x0e);   // 发送模式,8CRC校验,IRQ中断显示,上电发送
复制代码


到这里,nRF24L01无线芯片的一些基本操作和注意事项就是这样。



评分

参与人数 1黑币 +8 收起 理由
stkh + 8

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏7 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:300682 发表于 2018-5-4 14:42 | 只看该作者
大神,红蓝两个颜色没有显示,可以详细说一下哪个是地址哪个是数据吗?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表