發射數據時:
(1)首先將nRF24L01配置為發射模式
(2)①接着把接收節點地址TX_ADDR和有效數據TX_PLD按照時序由SPI口寫入nRF24L01緩存區,TX_PLD必須在CSN為低時連續寫入,而TX_ADDR在發射時寫入一次即可,然后CE置為高電平並保持至少10μs,延遲130μs后發射數據;
②若自動應答開啟,那么nRF24L01在發射數據后立即進入接收模式,接收應答信號(自動應答接收地址應該與接收節點地址TX_ADDR一致)。如果收到應答,則認為此次通信成功,TX_DS置高,同時TX_PLD從TXFIFO中清除;若未收到應答,則自動重新發射該數據(自動重發已開啟),若重發次數(ARC)達到上限,MAX_RT置高,TXFIFO中數據保留以便再次重發;MAX_RT或TX_DS置高時,使IRQ變低,產生中斷,通知MCU。最后發射成功時,若CE為低則nRF24L01進入空閑模式1;若發送堆棧中有數據且CE為高,則進入下一次發射;若發送堆棧中無數據且CE為高,則進入空閑模式2。
1 /********************************************************************** 2 配置NRF為TX模式,並發送一個數據包 3 輸入參數tfbuf:即將要發送出去的數據區首地址 4 ***********************************************************************/ 5 void NRF_SendPacket(u8* tfbuf) 6 { 7 CE_LOW; //拉低CE,進入待機模式,准備開始往NRF中的寄存器中寫入數據 10 SPI_Write_Buf(WR_TX_PLOAD, tfbuf, TX_PLOAD_WIDTH); //將數據寫入TX端的FIFO中,寫入的個數與TX_PLOAD_WIDTH設置值相同 12 SPI_Write_Byte(WRITE_REG_CMD + CONFIG, 0x0e); //將NRF配置成發射模式 13 SPI_Write_Byte(WRITE_REG_CMD + STATUS, 0x7e); //寫0111 xxxx 給STATUS,清除所有中斷標志,防止一進入發射模式就觸發中斷 14 15 CE_HIGH; //拉高CE,准備發射TX端FIFO中的數據 16 17 delay_ms(1); //CE拉高后,需要延遲至少130us 18 }
接收數據時:
(1)首先將nRF24L01配置為接收模式,接着延遲130μs進入接收狀態等待數據的到來
(2)當接收方檢測到有效的地址和CRC時,就將數據包存儲在RXFIFO中,同時中斷標志位RX_DR置高,IRQ變低,產生中斷,通知MCU去取數據。若此時自動應答開啟,接收方則同時進入發射狀態回傳應答信號。最后接收成功時,若CE變低,則nRF24L01進入空閑模式1。
1 /********************************************************************** 2 從NRF的RX的FIFO中讀取一組數據包 3 輸入參數rx_buf:FIFO中讀取到的數據的保存區域首地址 4 ***********************************************************************/ 5 void NRF_ReceivePacket(u8* rx_buf) 6 { 7 CE_LOW; 8 9 SPI_Read_Buf(RD_RX_PLOAD,rx_buf,RX_PLOAD_WIDTH); //從RX端的FIFO中讀取數據,並存入指定的區域,注意:讀取完FIFO中的數據后,NRF會自動清除其中的數據 10 SPI_Write_Byte(WRITE_REG_CMD+STATUS,sta); //接收到數據后RX_DR,TX_DS,MAX_PT都置高為1,通過寫1來清楚中斷標志 11 12 CE_HIGH; //重新拉高CE,讓其重新處於接收模式,准備接收下一個數據 13 }
①接收地址與發送地址為什么要設定成一樣的?
a.了解接收端與發送端的職責:
發送端(手柄)的職責:發送數據給接收端,接收某接收端的應答信號。
接收端(飛機)的職責:接收發送端發送的數據,發送應答信號給發送端。
b.對接收&發送地址的闡述:
1.
因此程序中要將發送地址和接收地址配成一樣的,這樣發射端可以正常收到接收端發送的應答信號,確保通信成功。
1 u8 TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //--本地地址 2 u8 RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //此地址用來配置本機NRF的RX0通道的地址,同時為了能正常收到應答信號,此地址一般都和上面的地址配置相同
寫寄存器進行TX_ADDR,TX_ADDR地址配置:
1 SPI_Write_Buf(WRITE_REG_CMD + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); 2 SPI_Write_Buf(WRITE_REG_CMD + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH);
②如何拋開接收端(飛機),來進行調試(遙控器)發送是否成功?
NRF24L01是收發雙方都需要編程的器件,這就對調試方法產生了一定的要求,如果兩塊一起調,那么通訊不成功,根本不知道是發的問題還是收的問題;
發送方:發送-等應答-(自動重發)-觸發中斷 可是這樣的流程就已經把接收方給牽涉進來了,就是說一定要接收方正確收到數據並且回送應答信號之后發送方才能觸發中斷,結束一次完整的發送。可是這跟我們的初衷不相符,我們想單獨調試發送,完全拋開接收,這樣就要去配置一些參數來取消自動應答,取消自動重發,讓發送方達到發出數據就算成功的目的。
於是通過以下三語句將發送端的流程就變成了發送-觸發中斷。這樣就拋開了接收方,可以專心去調試發送端
1 //測試NRF作為發射端的時候是否能發出數據的測試代碼,程序正常運行時,可以注釋掉 2 SPI_Write_Byte(WRITE_REG_CMD + SETUP_RETR, 0x00); 3 SPI_Write_Byte(WRITE_REG_CMD + EN_AA, 0x00); 4 SPI_Write_Byte(WRITE_REG_CMD + EN_RXADDR, 0x00);
參考博客:
發送地址和接收地址問題參考https://blog.csdn.net/qq_26602023/article/details/51016724
調試單端參考https://blog.csdn.net/q553716434/article/details/9996985