一、NRF24L01的相關介紹
1.2 引腳的介紹
關于SPI的引腳就不再說了,這里介紹其余的兩個引腳:
????????CE 模塊控制引腳:芯片開啟信號,激活RX或TX模式
????????IRQ 模塊中斷信號輸出引腳:其低電平有效,也就是中斷時變為低電平,要使用中斷時就設置為上拉輸入。。我們也可以屏蔽中斷信號,直接將這個引腳設置為下拉輸入。在以下三種情況變低:
????????????????????????Tx FIFO 發完并且收到ACK(使能ACK情況下)
????????????????????????Rx FIFO 收到數據
????????????????????????達到最大重發次數
1.3 NRF工作模式的介紹
????????NRF24L01的工作模式,由CE和CONFIG寄存器(0X00)的PWR_UP(第1位)和PRIM_RX(第0位)位共同控制。
NRF24L01所處模式 | PWR_UP位狀態 | PRIM_RX 位狀態 | CE | FIFO 寄存器狀態 |
---|---|---|---|---|
關斷模式 Shutdown | 0 | - | - | - |
待機模式? Standby | 1 | - | 0 | 無數據傳輸 |
發射空閑模式 Idle-TX | 1 | 0 | 1 | TX FIFO為空 |
發射模式? TX | 1 | 0 | 1 | ????????????????? 數據在TX FIFO寄存器中 ????????????????停留在發送模式,直至發送完成 |
接收模式? RX | 1 | 1 | 1 | - |
1.3.1?Shutdown 關斷工作模式
????????在Shutdown 工作模式下,Si24R1所有收發功能模塊關閉,芯片停止工作,消耗電流最小,但所有內部寄存器值和FIFO值保持不變,仍可通過SPI實現對寄存器的讀寫。 設置CONFIG寄存器的PWR_UP位的值為0,芯片立即返回到Shutdown工作模式。
1.3.2?Standby 待機工作模式
?????????在Standby 工作模式,只有晶體振蕩器電路工作,保證了芯片在消耗較少電流的同 時能夠快速啟動。設置CONFIG寄存器下的PWR_UP位的值為1,芯片待時鐘穩定后 進入Standby 模式。芯片的時鐘穩定時間一般為1.5~2ms,與晶振的性能有關。當引腳 CE=1 時,芯片將由Standby 模式進入到 Idle-TX 或 RX 模式,當 CE=0 時,芯片將由 Idle-TX、TX 或 RX模式返回到Standby模式。
1.3.3?Idle-TX 發射空閑工作模式
????????在Idle-TX 工作模式下,晶體振蕩器電路及時鐘電路工作。相比于Standby模式, 芯片消耗更多的電流。當發送端TX FIFO寄存器為空,并且引腳CE=1時,芯片進入到 Idle-TX 模式。在該模式下,如果有新的數據包被送到TX FIFO中,芯片內部的電路將 立即啟動,切換到TX模式將數據包發送。
???????? 在Standby 和 Idle-TX 工作模式下,所有內部寄存器值和 FIFO 值保持不變,仍可 通過SPI實現對寄存器的讀寫。
1.3.4?TX 發射工作模式
????????當需要發送數據時,需要切換到TX工作模式。芯片進入到TX工作模式的條件為: TX FIFO 中有數據, CONFIG寄存器的PWR_UP位的值為1,PRIM_RX位的值為0, 同時要求引腳CE上有一個至少持續10us的高脈沖。Idle-TX模式切換到TX模式的時 間為 120us~130us 之間,但不會超過 130us。單包數據發送完成后,如果 CE=1, 則由 TX FIFO的狀態來決定芯片所處的工作模式,當TX FIFO還有數據,芯片繼續保持在 TX工作模式,并發送下一包數據;當TX FIFO沒有數據,芯片返回Idle-TX模式;如 果CE=0,立即返回Standby模式。數據發射完成后,芯片產生數據發射完成中斷。
1.3.5 RX接收工作模式
????????當需要接收數據時,需要切換到RX工作模式。芯片進入到RX工作模式的條件為: 設置寄存器CONFIG的PWR_UP位的值為1,PRIM_RX位的值為1,并且引腳CE=1。 芯片由Standby 模式切換到RX模式的時間為120~130us。當接收到數據包的地址與芯片的地址相同,并且CRC檢查正確時,數據會自動存入RX FIFO,并產生數據接收中 斷。芯片最多可以同時存三個有效數據包,當FIFO已滿,接收到的數據包被自動丟掉。
二、NRF24L01的初始化
首先是關于引腳的初始化,至于SPI時序這里就不多介紹了,可以看這篇文章協議篇之SPI通信(軟件篇),而本篇文章就是基于這篇文章寫的。至于是使用SPI的哪個模式可以看手冊,這里我截取出來了:其中空閑時SCK為低電平,第一個邊沿采樣,所以使用模式0。
void NRF24L01_Init(void)
{/***** NRF的GPIO初始化 *****/GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PB端口時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能PA端口時鐘GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Pin = NRF_CE_PIN; //推挽 (配置CE) GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化指定IOGPIO_InitStructure.GPIO_Pin = NRF_IRQ_PIN;//配置IRQGPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //PB15 上拉輸入 GPIO_Init(GPIOA,&GPIO_InitStructure);my_spi_init();NRF_CE(0); //使能24L01SPI_NSS(1); //SPI片選取消
}
NRF24L01的通信條件:
1.? ?發射接收頻道相同(設置頻道寄存器RF_CH? 0-125);
2.? ?發射接收地址相同(設置TX_ADDR和RX_ADDR_P0相同? 5個8位地址);
3.? ?發射接收數據寬度相等( n<=32);
4.? ?發射接收速率相同(250k 1M 2M);
三、NRF的命令以及寄存器
3.1? NRF的命令
????????要實現對NRF的讀寫操作,就需要將命令以及寄存器地址結合起來使用,來實現對寄存器的操作,命令如下:
/************************* NRF24L01寄存器操作命令 *************************/
#define NRF_READ_REG 0x00 //讀配置寄存器,低5位為寄存器地址
#define NRF_WRITE_REG 0x20 //寫配置寄存器,低5位為寄存器地址
#define RD_RX_PLOAD 0x61 //讀RX有效數據,1~32字節
#define WR_TX_PLOAD 0xA0 //寫TX有效數據,1~32字節
#define FLUSH_TX 0xE1 //清除TX FIFO寄存器.發射模式下用
#define FLUSH_RX 0xE2 //清除RX FIFO寄存器.接收模式下用
#define REUSE_TX_PL 0xE3 //重新使用上一包數據,CE為高,數據包被不斷發送.
#define NOP 0xFF //空操作,可以用來讀狀態寄存器
3.2? NRF的寄存器
3.2.1?配置寄存器(CONFIG,0X00)
3.2.2?自動應答使能寄存器(EN_AA,0X01)
3.2.3?RX地址使能寄存器(EN_RXADDR,0X02)
3.2.4?自動重發設置寄存器(SETUP_RETR,0X04)
3.2.5?射頻頻率設置寄存器(RF_CH,0X05)
頻率計算公式:2400+RF_CH? (Mhz)
3.2.6?射頻配置寄存器(RF_SETUP,0X06)
3.2.7?狀態寄存器(STATUS,0X07)
3.2.8?數據通道接收地址寄存器(RX_ADDR_P0~P5,0X0A~0X0F)
3.2.9?發送地址設置寄存器(TX_ADDR,0X10)
3.2.10?接收通道有效數據寬度設置寄存器(RX_PW_P0~P5,0X11~0X16)
類似的,其他通道方法同RX_PW_P0。
四、NRF的檢查
????????時序以及初始化搞好了,那么如何檢測時序以及NRF是否正確呢?別的芯片一般可以通過讀ID來判斷,那么這個芯片的方法是往可讀可寫寄存器寫數據然后讀里面的數據是否正確。我們往發送通道寫5個字節的數據,然后挨個讀取內容,內容一致就說明檢測正確,否則失敗。
uint8_t NRF24L01_Check(void)
{u8 buf[5] = { 0x01,0x01,0x01,0x01,0x01 };u8 i;?MySPI_WriteLen(NRF_WRITE_REG+TX_ADDR,buf,5);//寫入5個字節的地址MySPI_ReadLen(TX_ADDR,buf,5); //讀出寫入的地址for(i=0;i<5;i++)if(buf[i]!=0x01)break;if(i!=5)return 1;//檢測24L01錯誤return 0;?? ??? ? //檢測到24L01
}
五、設置NRF為發送模式發送數據
? ? ? ? 在對NRF寄存器進行讀寫操作時,我們需要更改其工作模式,手冊里面有提到這句話:
注:只能在Shutdown、Standby和Idle-TX模式下才能對寄存器進行配置。
5.1 設置NRF為發射模式
? ? ? ? 由于對寄存器配置時不能為發射或者接收模式,所以我們先將CE置低位使其工作模式更改為待機模式,然后按照下列流程來配置NRF:????????
設置為發送模式的流程:
????????1)寫Tx 節點的地址 TX_ADDR
????????2)寫Rx 節點的地址(主要是為了使能Auto Ack) RX_ADDR_P0
????????3)使能AUTO ACK EN_AA
????????4)使能PIPE 0 EN_RXADDR
????????5)配置自動重發次數 SETUP_RETR
????????6)選擇通信頻率 RF_CH
????????7)配置發射參數(低噪放大器增益、發射功率、無線速率) RF_SETUP
????????8)配置24L01 的基本參數以及切換工作模式 CONFIG。
????????首先是寫Tx節點地址,我們定義有關數組,存放五個字節的數據(TX_ADDR長度有40位,看上面關于他的介紹)利用寫寄存器命令和TX_ADDR寄存器地址將這五個字節的地址寫入。
? ? ? ? 第二步是寫Rx節點地址,主要是為了使能自動應答,其地址和Tx節點地址相同,可以看關于Ack模式的介紹有這么一段話“接收端在發送ACK信號時,取接收管道地址作為目標地址來發送ACK信號,所 以發送端需要設置接收管道0地址與自身發送地址相同,以便接收ACK信號”
? ? ? ? 第三步是配置使能自動應答寄存器,我們使能數據管道0自動確認,所以寫入0x01;具體為什么這么配置可以看上文3.2.2關于這個寄存器的介紹。
????????第四步是配置使能接收數據管道地址,由于我們發射端需要接收Ack信號,所以我們要使能數據管道0,寫入0x01。
? ? ? ? 第五步是設置自動重發間隔時間以及最大自動重發次數,低四位由于配置自動重發計數,高四位用于配置自動重發延時,可以看3.2.4關于這個寄存器的介紹。我這里配置為0x1a,設置自動重發間隔時間:500us + 86us;最大自動重發次數:10次。
? ? ? ? 第六步是設置通信頻率,其值可以為0-125,見3.2.5;我這里寫入40,也就是2440MHz。
? ? ? ? 第七步是配置發射參數,可以根據寄存器的介紹自己去配置。
? ? ? ? 第八步是配置基本參數以及切換工作模式,見寄存器的描述,這里代碼如下:
/***** 將NRF設置位發送模式 *****/
void NRF24L01_TX_Mode(void)
{NRF_CE(0);//將CE置低配置為待機模式才能對寄存器進行配置MySPI_WriteLen(NRF_WRITE_REG+TX_ADDR,(u8*)TX_ADDRESS,TX_ADR_WIDTH);//寫TX節點地址MySPI_WriteLen(NRF_WRITE_REG+RX_ADDR_P0,(u8*)TX_ADDRESS,RX_ADR_WIDTH);//設置RX節點地址,主要為了使能ACKMySPI_WriteByte(NRF_WRITE_REG+EN_AA,0x01);//使能通道0的自動應答MySPI_WriteByte(NRF_WRITE_REG+EN_RXADDR,0x01);//使能通道0的自動應答MySPI_WriteByte(NRF_WRITE_REG+SETUP_RETR,0x1a);//設置自動重發間隔時間:500us + 86us;最大自動重發次數:10次MySPI_WriteByte(NRF_WRITE_REG+RF_CH,40); //設置RF通道為40MySPI_WriteByte(NRF_WRITE_REG+RF_SETUP,0x0f); //設置TX發射參數,0db增益,2Mbps,低噪聲增益開啟MySPI_WriteByte(NRF_WRITE_REG+CONFIG,0x0e); //配置基本工作模式的參數;PWR_UP,EN_CRC,16BIT_CRC,接收模式,開啟所有中斷NRF_CE(1);//CE為高,10us后啟動發送
}
5.2? NRF發送數據
? ? ? ? 要想啟動NRF發送數據,我們先將CE拉低進入待機模式才能配置寄存器,利用寫函數加寫發射負載數據命令寫入要發送的數據,注意這個數據大小為1-32字節。然后我們啟動發送,將NRF的CE腳拉高進入發射模式,然后讀IQR引腳判斷是否發送完成(Tx FIFO發完并收到Ack變為低電平)。然后我們讀取狀態寄存器,其值代表的狀態可以看寄存器介紹的3.2.7,首先判斷是否到達最大重發次數,其中MAX_TX為0x10,而狀態寄存器第四位就是達到最大重發次數中斷位,其判斷發送完成原理也是如此。
/***********************************************************
函數名稱:NRF24L01_TxPacket(u8 *txbuf)
函數功能:啟動NRF24L01發送一次數據
入口參數:txbuf 待發送的數據首地址
返回參數:返回值:TX_OK,接收完成,0xff,錯誤代碼
************************************************************/
u8 NRF24L01_TxPacket(u8 *txbuf)
{u8 sta;NRF_CE(0);MySPI_WriteLen(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);//寫數據到TX BUF 32個字節NRF_CE(1);//啟動發送while(READ_IRQ!=0);//等待發送完成sta=MySPI_ReadByte(STATUS); //讀取狀態寄存器的值 MySPI_WriteByte(NRF_WRITE_REG+STATUS,sta); //清除TX_DS或MAX_RT中斷標志if(sta&MAX_TX)//達到最大重發次數{MySPI_WriteByte(FLUSH_TX,0xff);//清除TX FIFO寄存器 return MAX_TX; }if(sta&TX_OK)//發送完成{return TX_OK;}return 0xff;//其他原因發送失敗
}
六、設置NRF為接收模式并接收數據
6.1 設置NRF為接收模式
????????其流程如下,和發送模式配置原理類似,可以參考發送模式,這里不再介紹。但是需要注意的就是配置要和發送模式相同,否則會導致通信不上。
設置為發送模式的流程:
????????1)寫Rx 節點的地址 RX_ADDR_P0
????????2)使能AUTO ACK EN_AA
????????3)使能PIPE 0 EN_RXADDR
????????4)選擇通信頻率 RF_CH
????????5)選擇通道0 有效數據寬度 RX_PW_P0
????????6)配置發射參數(低噪放大器增益、發射功率、無線速率) RF_SETUP
????????7)配置24L01 的基本參數以及切換工作模式 CONFIG。
/***** 將NRF設置為接收模式 *****/
void NRF24L01_RX_Mode(void)
{NRF_CE(0); MySPI_WriteLen(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH);//設置RX節點地址MySPI_WriteByte(NRF_WRITE_REG+EN_AA,0x01);//使能通道0的自動應答MySPI_WriteByte(NRF_WRITE_REG+EN_RXADDR,0x01);//使能通道0的自動應答MySPI_WriteByte(NRF_WRITE_REG+RF_CH,40); //設置RF通道為40MySPI_WriteByte(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//選擇通道0的有效數據寬度 MySPI_WriteByte(NRF_WRITE_REG+RF_SETUP,0x0f); //設置TX發射參數,0db增益,2Mbps,低噪聲增益開啟MySPI_WriteByte(NRF_WRITE_REG+CONFIG,0x0f); //配置基本工作模式的參數;PWR_UP,EN_CRC,16BIT_CRC,接收模式,開啟所有中斷NRF_CE(1);//CE為高,10us后啟動發送
}
6.2 接收數據
? ? ? ? 通過讀取狀態寄存器的值判斷是否接收到了數據,如果接收到了數據就將數據讀取到數組并清除Rx FIFO寄存器方便下次的接收。
/***********************************************************
函數名稱:NRF24L01_RxPacket(u8 *rxbuf)
函數功能:啟動NRF24L01接收一次數據
入口參數:rxbuf:待接收數據首地址
返回參數:返回值:0,接收完成;其他,錯誤代碼
************************************************************/
u8 NRF24L01_RxPacket(u8 *rxbuf)
{u8 sta; sta=MySPI_ReadByte(STATUS); //讀取狀態寄存器的值 MySPI_WriteByte(NRF_WRITE_REG+STATUS,sta); //清除TX_DS或MAX_RT中斷標志if(sta&RX_OK)//接收到數據{MySPI_ReadLen(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//讀取數據MySPI_WriteByte(FLUSH_RX,0xff);//清除RX FIFO寄存器 return 0; } return 1;//沒收到任何數據
}
nrf24l01.c
#include "stm32f10x.h" // Device header
#include "nrf24l01.h"
#include "spi.h"const u8 TX_ADDRESS[TX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //發送地址
const u8 RX_ADDRESS[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};void NRF24L01_Init(void)
{/***** NRF的GPIO初始化 *****/GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PB端口時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能PA端口時鐘GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Pin = NRF_CE_PIN; //推挽 (配置CE) GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化指定IOGPIO_InitStructure.GPIO_Pin = NRF_IRQ_PIN;//配置IRQGPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //PB15 上拉輸入 GPIO_Init(GPIOA,&GPIO_InitStructure);my_spi_init();NRF_CE(0); //使能24L01SPI_NSS(1); //SPI片選取消
}
/***** 檢測NRF 成功為0 *****/
uint8_t NRF24L01_Check(void)
{u8 buf[5] = { 0x01,0x01,0x01,0x01,0x01 };u8 i; MySPI_WriteLen(NRF_WRITE_REG+TX_ADDR,buf,5);//寫入5個字節的地址MySPI_ReadLen(TX_ADDR,buf,5); //讀出寫入的地址for(i=0;i<5;i++)if(buf[i]!=0x01)break;if(i!=5)return 1;//檢測24L01錯誤return 0; //檢測到24L01
}
/***** 將NRF設置位發送模式 *****/
void NRF24L01_TX_Mode(void)
{NRF_CE(0);//將CE置低配置為待機模式才能對寄存器進行配置MySPI_WriteLen(NRF_WRITE_REG+TX_ADDR,(u8*)TX_ADDRESS,TX_ADR_WIDTH);//寫TX節點地址MySPI_WriteLen(NRF_WRITE_REG+RX_ADDR_P0,(u8*)TX_ADDRESS,RX_ADR_WIDTH);//設置RX節點地址,主要為了使能ACKMySPI_WriteByte(NRF_WRITE_REG+EN_AA,0x01);//使能通道0的自動應答MySPI_WriteByte(NRF_WRITE_REG+EN_RXADDR,0x01);//使能通道0的自動應答MySPI_WriteByte(NRF_WRITE_REG+SETUP_RETR,0x1a);//設置自動重發間隔時間:500us + 86us;最大自動重發次數:10次MySPI_WriteByte(NRF_WRITE_REG+RF_CH,40); //設置RF通道為40MySPI_WriteByte(NRF_WRITE_REG+RF_SETUP,0x0f); //設置TX發射參數,0db增益,2Mbps,低噪聲增益開啟MySPI_WriteByte(NRF_WRITE_REG+CONFIG,0x0e); //配置基本工作模式的參數;PWR_UP,EN_CRC,16BIT_CRC,接收模式,開啟所有中斷NRF_CE(1);//CE為高,10us后啟動發送
}
/***** 將NRF設置為接收模式 *****/
void NRF24L01_RX_Mode(void)
{NRF_CE(0); MySPI_WriteLen(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH);//設置RX節點地址MySPI_WriteByte(NRF_WRITE_REG+EN_AA,0x01);//使能通道0的自動應答MySPI_WriteByte(NRF_WRITE_REG+EN_RXADDR,0x01);//使能通道0的自動應答MySPI_WriteByte(NRF_WRITE_REG+RF_CH,40); //設置RF通道為40MySPI_WriteByte(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//選擇通道0的有效數據寬度 MySPI_WriteByte(NRF_WRITE_REG+RF_SETUP,0x0f); //設置TX發射參數,0db增益,2Mbps,低噪聲增益開啟MySPI_WriteByte(NRF_WRITE_REG+CONFIG,0x0f); //配置基本工作模式的參數;PWR_UP,EN_CRC,16BIT_CRC,接收模式,開啟所有中斷NRF_CE(1);//CE為高,10us后啟動發送
}/***********************************************************
函數名稱:NRF24L01_TxPacket(u8 *txbuf)
函數功能:啟動NRF24L01發送一次數據
入口參數:txbuf 待發送的數據首地址
返回參數:返回值:TX_OK,接收完成,0xff,錯誤代碼
************************************************************/
u8 NRF24L01_TxPacket(u8 *txbuf)
{u8 sta;NRF_CE(0);MySPI_WriteLen(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);//寫數據到TX BUF 32個字節NRF_CE(1);//啟動發送while(READ_IRQ!=0);//等待發送完成sta=MySPI_ReadByte(STATUS); //讀取狀態寄存器的值 MySPI_WriteByte(NRF_WRITE_REG+STATUS,sta); //清除TX_DS或MAX_RT中斷標志if(sta&MAX_TX)//達到最大重發次數{MySPI_WriteByte(FLUSH_TX,0xff);//清除TX FIFO寄存器 return MAX_TX; }if(sta&TX_OK)//發送完成{return TX_OK;}return 0xff;//其他原因發送失敗
}/***********************************************************
函數名稱:NRF24L01_RxPacket(u8 *rxbuf)
函數功能:啟動NRF24L01接收一次數據
入口參數:rxbuf:待接收數據首地址
返回參數:返回值:0,接收完成;其他,錯誤代碼
************************************************************/
u8 NRF24L01_RxPacket(u8 *rxbuf)
{u8 sta; sta=MySPI_ReadByte(STATUS); //讀取狀態寄存器的值 MySPI_WriteByte(NRF_WRITE_REG+STATUS,sta); //清除TX_DS或MAX_RT中斷標志if(sta&RX_OK)//接收到數據{MySPI_ReadLen(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//讀取數據MySPI_WriteByte(FLUSH_RX,0xff);//清除RX FIFO寄存器 return 0; } return 1;//沒收到任何數據
}
nrf24l01.h
#ifndef __NRF24L010_H
#define __NRF24L010_H#include "stm32f10x.h" // Device header#define NRF_IRQ_PORT GPIOA
#define NRF_IRQ_PIN GPIO_Pin_8
#define NRF_CE_PORT GPIOB
#define NRF_CE_PIN GPIO_Pin_11#define NRF_CE(x) NRF_CE_PORT->BSRR = NRF_CE_PIN<<(16*(!x))
#define READ_IRQ (BitAction)(NRF_IRQ_PORT->IDR & NRF_IRQ_PIN)/************************* NRF24L01寄存器操作命令 *************************/
#define NRF_READ_REG 0x00 //讀配置寄存器,低5位為寄存器地址
#define NRF_WRITE_REG 0x20 //寫配置寄存器,低5位為寄存器地址
#define RD_RX_PLOAD 0x61 //讀RX有效數據,1~32字節
#define WR_TX_PLOAD 0xA0 //寫TX有效數據,1~32字節
#define FLUSH_TX 0xE1 //清除TX FIFO寄存器.發射模式下用
#define FLUSH_RX 0xE2 //清除RX FIFO寄存器.接收模式下用
#define REUSE_TX_PL 0xE3 //重新使用上一包數據,CE為高,數據包被不斷發送.
#define NOP 0xFF //空操作,可以用來讀狀態寄存器
//SPI(NRF24L01)寄存器地址
#define CONFIG 0x00 //配置寄存器地址;bit0:1接收模式,0發射模式;bit1:電選擇;bit2:CRC模式;bit3:CRC使能;//bit4:中斷MAX_RT(達到最大重發次數中斷)使能;bit5:中斷TX_DS使能;bit6:中斷RX_DR使能
#define EN_AA 0x01 //使能自動應答功能 bit0~5,對應通道0~5
#define EN_RXADDR 0x02 //接收地址允許,bit0~5,對應通道0~5
#define SETUP_AW 0x03 //設置地址寬度(所有數據通道):bit1,0:00,3字節;01,4字節;02,5字節;
#define SETUP_RETR 0x04 //建立自動重發;bit3:0,自動重發計數器;bit7:4,自動重發延時 250*x+86us
#define RF_CH 0x05 //RF通道,bit6:0,工作通道頻率;
#define RF_SETUP 0x06 //RF寄存器;bit3:傳輸速率(0:1Mbps,1:2Mbps);bit2:1,發射功率;bit0:低噪聲放大器增益
#define STATUS 0x07 //狀態寄存器;bit0:TX FIFO滿標志;bit3:1,接收數據通道號(最大:6);bit4,達到最多次重發//bit5:數據發送完成中斷;bit6:接收數據中斷;
#define MAX_TX 0x10 //達到最大發送次數中斷
#define TX_OK 0x20 //TX發送完成中斷
#define RX_OK 0x40 //接收到數據中斷#define OBSERVE_TX 0x08 //發送檢測寄存器,bit7:4,數據包丟失計數器;bit3:0,重發計數器
#define CD 0x09 //載波檢測寄存器,bit0,載波檢測;
#define RX_ADDR_P0 0x0A //數據通道0接收地址,最大長度5個字節,低字節在前
#define RX_ADDR_P1 0x0B //數據通道1接收地址,最大長度5個字節,低字節在前
#define RX_ADDR_P2 0x0C //數據通道2接收地址,最低字節可設置,高字節,必須同RX_ADDR_P1[39:8]相等;
#define RX_ADDR_P3 0x0D //數據通道3接收地址,最低字節可設置,高字節,必須同RX_ADDR_P1[39:8]相等;
#define RX_ADDR_P4 0x0E //數據通道4接收地址,最低字節可設置,高字節,必須同RX_ADDR_P1[39:8]相等;
#define RX_ADDR_P5 0x0F //數據通道5接收地址,最低字節可設置,高字節,必須同RX_ADDR_P1[39:8]相等;
#define TX_ADDR 0x10 //發送地址(低字節在前),ShockBurstTM模式下,RX_ADDR_P0與此地址相等
#define RX_PW_P0 0x11 //接收數據通道0有效數據寬度(1~32字節),設置為0則非法
#define RX_PW_P1 0x12 //接收數據通道1有效數據寬度(1~32字節),設置為0則非法
#define RX_PW_P2 0x13 //接收數據通道2有效數據寬度(1~32字節),設置為0則非法
#define RX_PW_P3 0x14 //接收數據通道3有效數據寬度(1~32字節),設置為0則非法
#define RX_PW_P4 0x15 //接收數據通道4有效數據寬度(1~32字節),設置為0則非法
#define RX_PW_P5 0x16 //接收數據通道5有效數據寬度(1~32字節),設置為0則非法
#define NRF_FIFO_STATUS 0x17 //FIFO狀態寄存器;bit0,RX FIFO寄存器空標志;bit1,RX FIFO滿標志;bit2,3,保留//bit4,TX FIFO空標志;bit5,TX FIFO滿標志;bit6,1,循環發送上一數據包.0,不循環;
//
//24L01發送接收數據寬度定義
#define TX_ADR_WIDTH 5 //5字節的地址寬度
#define RX_ADR_WIDTH 5 //5字節的地址寬度
#define TX_PLOAD_WIDTH 32 //32字節的用戶數據寬度
#define RX_PLOAD_WIDTH 32 //32字節的用戶數據寬度void NRF24L01_Init(void); //初始化
void NRF24L01_RX_Mode(void); //配置為接收模式
void NRF24L01_TX_Mode(void); //配置為發送模式
u8 NRF24L01_Write_Reg(u8 reg, u8 value); //寫寄存器
u8 NRF24L01_Check(void); //檢查24L01是否存在
u8 NRF24L01_TxPacket(u8 *txbuf); //發送一個包的數據
u8 NRF24L01_RxPacket(u8 *rxbuf); //接收一個包的數據
void NRF24L01_Check_detection(void);
void NRF24L01_Text(u8 mode);#endif