找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 6036|回復(fù): 1
打印 上一主題 下一主題
收起左側(cè)

nRF24L01應(yīng)用筆記(下)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:69862 發(fā)表于 2015-7-24 22:44 | 只看該作者 回帖獎(jiǎng)勵(lì) |正序?yàn)g覽 |閱讀模式
本帖最后由 xiao_yp2014 于 2016-6-7 13:55 編輯

上接:nRF24L01應(yīng)用筆記(上)        http://www.torrancerestoration.com/bbs/dpj-37580-1.html
如何快速搞通“NRF24L01”,你造嗎? http://www.torrancerestoration.com/bbs/dpj-51459-1.html





nRF24L01應(yīng)用筆記(下)

上面一篇說了一下調(diào)試的方法和步驟,接下來說一下程序當(dāng)中需要注意的地方。首先,不要把nRF24L01芯片想得太神秘,其實(shí)就是一個(gè)無線通信的芯片,通信的一些參數(shù)(通信速率,地址位長(zhǎng)度,數(shù)據(jù)位長(zhǎng)度)需要寫內(nèi)部寄存器來設(shè)置。單片機(jī)和芯片是用SPI通信,這個(gè)就不再說了,那么,就直接進(jìn)入主題。

一、nRF24L01的寄存器
首先來了解一下寄存器(下面這些寄存器地址只是一個(gè)偏移地址)

  1. #define CONFIG      0x00  // 配置寄存器地址
  2. #define EN_AA       0x01  // 使能ACK自動(dòng)應(yīng)答功能地址
  3. #define EN_RXADDR   0x02  // 接收地址允許地址
  4. #define SETUP_AW    0x03  // 設(shè)置地址寬度地址
  5. #define SETUP_RETR  0x04  // 建立自動(dòng)應(yīng)答的時(shí)間地址
  6. #define RF_CH       0x05  // 射頻通道地址
  7. #define RF_SETUP    0x06  // 射頻寄存器地址
  8. #define STATUS      0x07  // 狀態(tài)寄存器地址
  9. #define OBSERVE_TX  0x08  // 發(fā)送檢測(cè)寄存器地址
  10. #define CD          0x09  // 載波檢測(cè)地址
  11. #define RX_ADDR_P0  0x0A  // 數(shù)據(jù)通道0接收地址,最大數(shù)據(jù)長(zhǎng)度5個(gè)字節(jié)
  12. #define RX_ADDR_P1  0x0B  // 數(shù)據(jù)通道1接收地址,最大數(shù)據(jù)長(zhǎng)度5個(gè)字節(jié)
  13. #define RX_ADDR_P2  0x0C  // 數(shù)據(jù)通道2接收地址,最低字節(jié)可設(shè)置,高字節(jié)部分必須與RX_ADDR相同
  14. #define RX_ADDR_P3  0x0D  // 數(shù)據(jù)通道3接收地址,最低字節(jié)可設(shè)置,高字節(jié)部分必須與RX_ADDR相同
  15. #define RX_ADDR_P4  0x0E  // 數(shù)據(jù)通道4接收地址,最低字節(jié)可設(shè)置,高字節(jié)部分必須與RX_ADDR相同
  16. #define RX_ADDR_P5  0x0F  // 數(shù)據(jù)通道5接收地址,最低字節(jié)可設(shè)置,高字節(jié)部分必須與RX_ADDR相同
  17. #define TX_ADDR     0x10  // 發(fā)送地址,在增強(qiáng)型模式下,要與RX_ADDR_P0相同
  18. #define RX_PW_P0    0x11  // 接收數(shù)據(jù)通道0有效數(shù)據(jù)寬度(1~32個(gè)字節(jié))
  19. #define RX_PW_P1    0x12  // 接收數(shù)據(jù)通道1有效數(shù)據(jù)寬度(1~32個(gè)字節(jié))
  20. #define RX_PW_P2    0x13  // 接收數(shù)據(jù)通道2有效數(shù)據(jù)寬度(1~32個(gè)字節(jié))
  21. #define RX_PW_P3    0x14  // 接收數(shù)據(jù)通道3有效數(shù)據(jù)寬度(1~32個(gè)字節(jié))
  22. #define RX_PW_P4    0x15  // 接收數(shù)據(jù)通道4有效數(shù)據(jù)寬度(1~32個(gè)字節(jié))
  23. #define RX_PW_P5    0x16  // 接收數(shù)據(jù)通道5有效數(shù)據(jù)寬度(1~32個(gè)字節(jié))
  24. #define FIFO_STATUS 0x17  // FIFO狀態(tài)寄存器地址
復(fù)制代碼



上面一些寄存器地址并不是真實(shí)的地址,是一個(gè)偏移地址,那實(shí)際地址如何表示呢?
實(shí)際地址 = 基地址 + 偏移地址


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

  1.         #define READ_REG    0x00  // 讀配置寄存器命令
  2. #define WRITE_REG   0x20  // 寫配置寄存器命令
  3. #define RD_RX_PLOAD 0x61  // 讀RX有效數(shù)據(jù)命令
  4. #define WR_TX_PLOAD 0xA0  // 寫TX有效數(shù)據(jù)命令
  5. #define FLUSH_TX    0xE1  // 清除TX_FIFO寄存器,應(yīng)用于發(fā)射模式
  6. #define FLUSH_RX    0xE2  // 清除RX_FIFO寄存器,應(yīng)用于接收模式
  7. #define REUSE_TX_PL 0xE3  // 應(yīng)用發(fā)射,重新發(fā)送上一包有效數(shù)據(jù)
  8. //#define NOP         0xFF  // 空操作命令,一般沒有使用
復(fù)制代碼



  上面一些寄存器地址并不是真實(shí)的地址,是一個(gè)偏移地址,那實(shí)際地址如何表示呢?
實(shí)際地址 = 基地址 + 偏移地址
在程序中就會(huì)有這樣寫,如下:

  1.         SPI_Write_Reg(WRITE_REG + RX_PW_P0, TX_ADR_WIDTH);          //接收數(shù)據(jù)通道0有效數(shù)據(jù)寬度5個(gè)字節(jié)
  2.     WRITE_REG + RX_PW_P0就是設(shè)置接收數(shù)據(jù)寬度的實(shí)際寄存器
復(fù)制代碼



三、nRF24L01初始化
初始化就是設(shè)置nRF24L01的默認(rèn)工作狀態(tài),和發(fā)送或接收的一些要求,比如選擇接收通道,速率,發(fā)射功率之類的東西,這些在網(wǎng)上都可以找到程序,我也就不多說了,只提一下需要注意的地方
SPI_Write_Reg(WRITE_REG + RF_CH, 40);       // 選擇射頻通道0x40
這個(gè)是設(shè)置射頻通道,后面的40可以隨便定義使用,只要發(fā)送和接收一致就行了,我是這樣處理的,可能還有其它的解釋。





四、nRF24L01設(shè)置寄存器
寄存器設(shè)置和我們使用51單片機(jī)是一樣的,都是寫一些參數(shù),來開啟或關(guān)閉某一個(gè)功能,唯一不同一點(diǎn)是,51單片機(jī)的地址是定義好了的,只需要向里面寫數(shù)據(jù)就可以了,但是nRF24L01不能這樣做,因?yàn)樗鼉?nèi)部沒有這個(gè)地址管理,就必須由主設(shè)備來選擇地址,才可以對(duì)號(hào)入座,向規(guī)定的寄存器寫正確的數(shù)據(jù)。
配置寄存器參數(shù)時(shí),要先寫地址,再寫參數(shù)。










    看看程序中是如何處理的
  1. SPI_Write_Reg(WRITE_REG + RX_PW_P0, TX_ADR_WIDTH);        //這個(gè)是調(diào)用下面的函數(shù)  

  2. unsigned char SPI_Write_Reg(unsigned char ucWrite_Reg, unsigned char ucWriteValue)
  3. {
  4.      unsigned char  ucStatus;
  5.      CSN = 0;                   // CSN置低,開始傳輸數(shù)據(jù)
  6.      ucStatus = SPI_Simulation(ucWrite_Reg); // 選擇寄存器,同時(shí)返回狀態(tài)字
  7.      SPI_Simulation(ucWriteValue);             // 然后寫數(shù)據(jù)到該寄存器
  8.      CSN = 1;                   // CSN拉高,結(jié)束數(shù)據(jù)傳輸
  9.      return(ucStatus);            // 返回狀態(tài)寄存器
  10. }
復(fù)制代碼



紅色是地址              
藍(lán)色是數(shù)據(jù)





五、nRF24L01的查詢方法(中斷查詢和狀態(tài)寄存器查詢,主要介紹狀態(tài)寄存器查詢方法)

nRF24L01的查詢方法有兩種:
1、中斷查詢

   IRQ:中斷信號(hào)。無線通信過程中 MCU 主要是通過 IRQ 與 NRF24L01 進(jìn)行通信。
   中斷查詢開啟后,當(dāng)接收成功或者發(fā)送成功在中斷引腳上面會(huì)有一個(gè)低電平,把IRQ引腳接在單片機(jī)的外部中斷引腳上面,就能夠?qū)崟r(shí)查詢。



2、狀態(tài)寄存器查詢
   狀態(tài)寄存器查詢:就是通過軟件查詢這個(gè)寄存器的置位或者是清零,來判斷是發(fā)送成功還是接收成功。




狀態(tài)寄存器查詢程序如下:

  1. unsigned char bdata StateFalg;//狀態(tài)標(biāo)志位,定義在bdata ,是可以位尋址。
  2. sbit RX_DR = StateFalg^6;        //接收中斷標(biāo)志位
  3. sbit TX_DS = StateFalg^5;        //發(fā)送中斷標(biāo)志位
  4. sbit MAX_RT = StateFalg^4;        //發(fā)送次數(shù)超過10次中斷標(biāo)志位

  5. StateFalg = SPI_Read_Reg(READ_REG+STATUS);  // 返回狀態(tài)寄存器
  6. SPI_Write_Reg(WRITE_REG+STATUS,StateFalg);  // 清零對(duì)應(yīng)中斷標(biāo)志

  7. if(RX_DR == 1)
  8. {
  9.       SPI_Read_Buf(RD_RX_PLOAD,RX_BUF, TX_PLOAD_WIDTH); //從FIFO緩存中讀取數(shù)據(jù),存入數(shù)組。
  10.       SPI_Write_Reg(FLUSH_RX,0);         //清除RX_FIFO寄存器
  11.         }
復(fù)制代碼





六、接收或發(fā)送模式的切換



        最后說一下模式的切換,模式切換可以在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
     默認(rèn)為“0

6MASK_RX_DR  可屏蔽中斷RX_DR
     1IRQ引腳不產(chǎn)生RX_DR 中斷
     0RX_DR 中斷產(chǎn)生時(shí)IRQ引腳為低電平

5MASK_TX_DS  可屏蔽中斷TX_DR
     1IRQ引腳不產(chǎn)生TX_DR 中斷
     0TX_DR 中斷產(chǎn)生時(shí)IRQ引腳為低電平

4MASK_MAX_RT  可屏蔽中斷MAX_RT
     1IRQ引腳不產(chǎn)生TX_DS中斷
     0MAX_RT中斷產(chǎn)生時(shí),IRQ引腳為低電平

3EN_CRC  CRC使能端
     如果EN_AA中任意一位為高,則EN_CRC強(qiáng)迫為高

2CRCO  CRC模式
     116CRC校驗(yàn)
     08CRC校驗(yàn)

1PWR_UP  芯片模式設(shè)置
     1:上電模式
     0:掉電模式

0PRIM_RX  接收或發(fā)射模式     
     1:接收模式
     0:發(fā)射模式

在程序中只需要對(duì)相應(yīng)的位置“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);                                  // 接收數(shù)據(jù)長(zhǎng)度
  4.         SPI_Write_Reg(WRITE_REG+CONFIG,0x0f);  // 接收模式,8CRC校驗(yàn),IRQ中斷顯示,上電發(fā)送

  5. 發(fā)送模式:
  6.         SPI_Write_Buf(TX_ADDR, ucTX_Address, TX_ADR_WIDTH);     // 寫入發(fā)送地址
  7.         SPI_Write_Buf(WR_TX_PLOAD, ucTxData, TX_PLOAD_WIDTH); //裝載數(shù)據(jù)到FIFO中
  8.          SPI_Write_Reg(WRITE_REG+CONFIG,0x0e);   // 發(fā)送模式,8CRC校驗(yàn),IRQ中斷顯示,上電發(fā)送
復(fù)制代碼


到這里,nRF24L01無線芯片的一些基本操作和注意事項(xiàng)就是這樣。



評(píng)分

參與人數(shù) 1黑幣 +8 收起 理由
stkh + 8

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏7 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:300682 發(fā)表于 2018-5-4 14:42 | 只看該作者
大神,紅藍(lán)兩個(gè)顏色沒有顯示,可以詳細(xì)說一下哪個(gè)是地址哪個(gè)是數(shù)據(jù)嗎?
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表