NRF24L01+的使用

NRF24L01+的使用

这是数据手册上的一个图例,根据它得到一个粗略的流程图:

NRF24L01+的使用


 发射数据

1)首先将nRF24L01配置为发射模式

2)接着把接收节点地址TX_ADDR和有效数据TX_PLD按照时序由SPI口写入nRF24L01缓存区,TX_PLD必须在CSN为低时连续写入,而TX_ADDR在发射时写入一次即可,然后CE置为高电平并保持至少10μs,延迟130μs后发射数据;

3)若自动应答开启,那么nRF24L01在发射数据后立即进入接收模式,接收应答信号(自动应答接收地址应该与接收节点地址TX_ADDR一致)。如果收到应答,则认为此次通信成功,TX_DS置高,同时TX_PLDTX FIFO中清除;若未收到应答,则自动重新发射该数据(自动重发已开启),若重发次数(ARC)达到上限,MAX_RT置高,TX FIFO中数据保留以便再次重发;MAX_RTTX_DS置高时,使IRQ变低,产生中断,通知MCU

4)最后发射成功时,CE为低则nRF24L01进入空闲模式1;   若发送堆栈中有数据且CE为高,则进入下一次发射;若发送堆栈中无数据且CE为高,则进入空闲模式2;

 

 

 

 

 

 

 

   接收数据

1)首先将nRF24L01配置为接收模式,接着延迟130μs进入接收状态等待数据的到来。

2)当接收方检测到有效的地址和CRC时,就将数据包存储在RX FIFO中,同时中断标志位RX_DR置高,IRQ变低,产生中断,通知MCU去取数据。

3)若此时自动应答开启,接收方则同时进入发射状态回传应答信号。最后接收成功时,若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 

 

初始化函数:

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);
}
这里注意,根据第一张图可知,进入接收模式后,只要CE不为低,就一直处于接收模式,可以不停滴接收数据。

 

进入发射模式并发送数据:

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,激发数据发送
 Sys_DelaynUs(20);
}

 

接收数据:

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;


中断处理函数

void EXTI9_5_IRQHandler(void)

{

u8 NEF24L01_State ;

if(EXTI_GetITStatus(EXTI_Line5) != RESET)   

{

PrintfUsart1("%s","进入发送端中断");

PrintfUsart1("\r\n");

if(NRF1.NRF_SPI_Ready)

{

NEF24L01_State = NRF24L01_Read(STATUS,&NRF1);

if(NEF24L01_State&0x20)               //数据发送完成中断

{

NRF1.NRF_SPI_TX_Time++ ;

            PrintfUsart1("%s","发送完成的次数:");

PrintfUsart1("%d",NRF1.NRF_SPI_TX_Time);

PrintfUsart1("\r\n");

}

if(NEF24L01_State&0x10)              //重发次数溢出中断

{

NRF1.NRF_SPI_MAX_RT_Time++ ;

PrintfUsart1("%s","重发溢出次数:");

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);

}