本帖最后由 xiao_yp2014 于 2016-6-7 13:55 編輯
如何快速搞通“NRF24L01”,你造嗎? http://www.zg4o1577.cn/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無線芯片的一些基本操作和注意事項就是這樣。
|