
這是數(shù)據(jù)手冊上的一個圖例,根據(jù)它得到一個粗略的流程圖:

發(fā)射數(shù)據(jù)
1)首先將nRF24L01配置為發(fā)射模式
2)接著把接收節(jié)點地址TX_ADDR和有效數(shù)據(jù)TX_PLD按照時序由SPI口寫入nRF24L01緩存區(qū),TX_PLD必須在CSN為低時連續(xù)寫入,而TX_ADDR在發(fā)射時寫入一次即可,然后CE置為高電平并保持至少10μs,延遲130μs后發(fā)射數(shù)據(jù);
3)若自動應答開啟,那么nRF24L01在發(fā)射數(shù)據(jù)后立即進入接收模式,接收應答信號(自動應答接收地址應該與接收節(jié)點地址TX_ADDR一致)。如果收到應答,則認為此次通信成功,TX_DS置高,同時TX_PLD從TX FIFO中清除;若未收到應答,則自動重新發(fā)射該數(shù)據(jù)(自動重發(fā)已開啟),若重發(fā)次數(shù)(ARC)達到上限,MAX_RT置高,TX FIFO中數(shù)據(jù)保留以便再次重發(fā);MAX_RT或TX_DS置高時,使IRQ變低,產(chǎn)生中斷,通知MCU。
4)最后發(fā)射成功時,若CE為低則nRF24L01進入空閑模式1; 若發(fā)送堆棧中有數(shù)據(jù)且CE為高,則進入下一次發(fā)射;若發(fā)送堆棧中無數(shù)據(jù)且CE為高,則進入空閑模式2;
接收數(shù)據(jù)
1)首先將nRF24L01配置為接收模式,接著延遲130μs進入接收狀態(tài)等待數(shù)據(jù)的到來。
2)當接收方檢測到有效的地址和CRC時,就將數(shù)據(jù)包存儲在RX FIFO中,同時中斷標志位RX_DR置高,IRQ變低,產(chǎn)生中斷,通知MCU去取數(shù)據(jù)。
3)若此時自動應答開啟,接收方則同時進入發(fā)射狀態(tài)回傳應答信號。最后接收成功時,若CE變低,則nRF24L01進入空閑模式1
#define
NRF24L01_READ_REG
0x00
#define
NRF24L01_WRITE_REG
0x20
#define
RD_RX_PLOAD
0x61
#define
WR_TX_PLOAD
0xA0
#define
FLUSH_TX
0xE1
#define
FLUSH_RX
0xE2
#define
REUSE_TX_PL
0xE3
#define
NOP
0xFF
#define
CONFIG
0x00
#define
EN_AA
0x01
#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
#define
RX_ADDR_P1
0x0B
#define
RX_ADDR_P2
0x0C
#define
RX_ADDR_P3
0x0D
#define
RX_ADDR_P4
0x0E
#define
RX_ADDR_P5
0x0F
#define
TX_ADDR
0x10
#define
RX_PW_P0
0x11
#define
RX_PW_P1
0x12
#define
RX_PW_P2
0x13
#define
RX_PW_P3
0x14
#define
RX_PW_P4
0x15
#define
RX_PW_P5
0x16
#define
FIFO_STATUS
0x17
初始化函數(shù):
void NRF24L01SPI_Init( NRF_t * NRF)
{
(NRF->SPI_Config)();
NRF->NRF_SPI_TX_Time = 0;
NRF->NRF_SPI_TX_Over = 0;
NRF->NRF_SPI_MAX_RT_Time =
0;
Sys_DelaynUs(130);
(NRF->CE_Low)();
Sys_DelaynMs(1);
(NRF->CSN_High)();
Sys_DelaynMs(1);
(NRF->IRQ_High)();
Sys_DelaynMs(1);
NRF24L01_Write_Buf(NRF24L01_WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH,NRF);
NRF24L01_Write_Buf(NRF24L01_WRITE_REG+RX_ADDR_P0,RX_ADDRESS,TX_ADR_WIDTH,NRF);
NRF24L01_RW_Reg(NRF24L01_WRITE_REG + EN_AA,
0x01,NRF);
NRF24L01_RW_Reg(NRF24L01_WRITE_REG + EN_RXADDR,
0x01,NRF);
NRF24L01_RW_Reg(NRF24L01_WRITE_REG +
RF_CH,0,NRF);
NRF24L01_RW_Reg(NRF24L01_WRITE_REG +
RX_PW_P0,TX_PLOAD_WIDTH,NRF);
NRF24L01_RW_Reg(NRF24L01_WRITE_REG + SETUP_RETR,
0x2a,NRF);
NRF24L01_RW_Reg(NRF24L01_WRITE_REG + RF_SETUP,
0x07,NRF);
}
進入接收模式:
void NRF24L01_RX_Mode(NRF_t * NRF)
{
(NRF->CE_Low)();
NRF24L01_RW_Reg(NRF24L01_WRITE_REG + CONFIG,
0x0F,NRF);
(NRF->CE_High)();
Sys_DelaynUs(130);
}
這里注意,根據(jù)第一張圖可知,進入接收模式后,只要CE不為低,就一直處于接收模式,可以不停滴接收數(shù)據(jù)。
進入發(fā)射模式并發(fā)送數(shù)據(jù):
void NRF24L01_TxPacket(u8* txbuf, NRF_t * NRF)
{
(NRF->CE_Low)();
NRF24L01_Write_Buf(NRF24L01_WRITE_REG +
RX_ADDR_P0,TX_ADDRESS, TX_ADR_WIDTH, NRF);
NRF24L01_Write_Buf(WR_TX_PLOAD, txbuf,
TX_PLOAD_WIDTH, NRF);
NRF24L01_RW_Reg(NRF24L01_WRITE_REG + CONFIG,
0x0E,NRF);
(NRF->CE_High)();
//置高CE,激發(fā)數(shù)據(jù)發(fā)送
Sys_DelaynUs(20);
}
接收數(shù)據(jù):
u8 NRF24L01_RxPacket(u8 * rxbuf, NRF_t * NRF)
{
unsigned char revale =
0;
u8 status;
status =
NRF24L01_Read(STATUS,NRF);
if(status &
0x40)
{
NRF24L01_Read_Buf(RD_RX_PLOAD,rxbuf,TX_PLOAD_WIDTH,NRF);
revale
=1;
}
NRF24L01_RW_Reg(NRF24L01_WRITE_REG+STATUS,
status,NRF);
return revale;
中斷處理函數(shù)
void
EXTI9_5_IRQHandler(void)
{
u8 NEF24L01_State ;
if(EXTI_GetITStatus(EXTI_Line5)
!= RESET)
{
PrintfUsart1("%s","進入發(fā)送端中斷");
PrintfUsart1("\r\n");
if(NRF1.NRF_SPI_Ready)
{
NEF24L01_State =
NRF24L01_Read(STATUS,&NRF1);
if(NEF24L01_State&0x20)
//數(shù)據(jù)發(fā)送完成中斷
{
NRF1.NRF_SPI_TX_Time++
;
PrintfUsart1("%s","發(fā)送完成的次數(shù):");
PrintfUsart1("%d",NRF1.NRF_SPI_TX_Time);
PrintfUsart1("\r\n");
}
if(NEF24L01_State&0x10)
//重發(fā)次數(shù)溢出中斷
{
NRF1.NRF_SPI_MAX_RT_Time++
;
PrintfUsart1("%s","重發(fā)溢出次數(shù):");
PrintfUsart1("%d",NRF1.NRF_SPI_MAX_RT_Time);
PrintfUsart1("\r\n");
}
NRF24L01_RW_Reg(NRF24L01_WRITE_REG + STATUS,
NEF24L01_State,&NRF1);
NRF1.NRF_SPI_TX_Over =
0;
}
EXTI_ClearITPendingBit(EXTI_Line5);
}
|