#include "NRF24L01.H" unsigned char RF_CH = 0x40; //RF频道 unsigned char NRF24L01_FLAG = 0; //NRF24L01当前状态标志 //DB7; 1接收模式 0发射模式 //DB6; 1有任务 0空闲 //DB5; 1发送成功 0发送失败(配合DB6检测是否发送成功) //DB4; 1NRF正常连接 0 检测不到连接 //DB3; 1接收到数据包 0 缓冲区无数据 //DB2; 1 ACK模式 0 NOACK模式 //DB1; 1发送完自动进入接收模式 0关闭自动切换模式 unsigned char DYNPD_LEN = 0; //用于存放动态数据包长度 unsigned char TX_ADDRESS[NRF24L01_ADR_LEN] = {0x12, 0x34, 0x56, 0x78, 0x90}; //本地地址 unsigned char RX_ADDRESS[NRF24L01_ADR_LEN] = {0x12, 0x34, 0x56, 0x78, 0x90}; //接收地址 //向从机发送一个字节数据并返回接收数据 /**************************************************/ unsigned char SPI_WriteRead ( unsigned char byte ) { unsigned char bit_ctr; for ( bit_ctr = 0; bit_ctr < 8; bit_ctr++ ) // 输出8位 { NRF_MOSI = ( byte & 0x80 ); // MSB TO MOSI byte = ( byte << 1 ); // shift next bit to MSB NRF_SCK = 1; byte |= NRF_MISO; // capture current MISO bit NRF_SCK = 0; } return byte; } //写NRF24L01寄存器,返回状态值 unsigned char NRF24L01_Write_Reg ( unsigned char reg, unsigned char value ) { unsigned char BackDate; NRF_CSN = 0; SPI_WriteRead ( reg ); BackDate = SPI_WriteRead ( value ); NRF_CSN = 1; return ( BackDate ); } //读NRF24L01寄存器,返回寄存器值 unsigned char NRF24L01_Read_Reg ( unsigned char reg ) { unsigned char BackDate; NRF_CSN = 0; SPI_WriteRead ( reg ); BackDate = SPI_WriteRead ( 0x00 ); NRF_CSN = 1; return ( BackDate ); } //读取缓冲区数据 void NRF24L01_Read_Buf ( unsigned char reg, unsigned char *pBuf, unsigned char bytes ) { unsigned char byte_ctr; NRF_CSN = 0; SPI_WriteRead ( reg ); for ( byte_ctr = 0; byte_ctr < bytes; byte_ctr++ ) { pBuf[byte_ctr] = SPI_WriteRead ( 0x00 ); } NRF_CSN = 1; } //向缓冲区写入数据 unsigned char NRF24L01_Write_Buf ( unsigned char reg, unsigned char *pBuf, unsigned char bytes ) { unsigned char status, byte_ctr; NRF_CSN = 0; status = SPI_WriteRead ( reg ); for ( byte_ctr = 0; byte_ctr < bytes; byte_ctr++ ) { SPI_WriteRead ( *pBuf++ ); } NRF_CSN = 1; return ( status ); } /* PIPEN 中断使能 PINEN 正反向特性 PICON 触发方式(电平或边沿检测) PIF 中断标志 */ void NRF24L01_Interrupt_P03 ( void ) { //P0M1|=SET_BIT3;P0M2&=~SET_BIT3; //input PICON &= ~ ( SET_BIT0 | SET_BIT1 ); PICON |= ( 0x00 ); //[1:0]=0.端口0 PICON |= SET_BIT5; //通道3=1.边沿触发 PINEN |= SET_BIT3; // 1 = 低电平/ 下降沿触发中断 PIPEN &= ~SET_BIT3; //0 = 关闭中断(高电平/ 上升沿触发中断) EIE |= SET_BIT1; //管脚中断,最多8个,中断号7 EA = 1; // 总中断 } //NRF24L01初始化函数 void NRF24L01_Init ( void ) { #if BK2423 NRF_CE = 0; NRF24L01_Write_Reg ( ACTIVATE_CMD, 0x73 ); NRF_CE = 1; #endif NRF_CSN = 1; // Spi disable NRF_SCK = 0; // Spi clock line init high NRF_CE = 0; //配置寄存器 NRF24L01_FLAG |= NRF24L01_AUTO_ACK; //是否开启应答模式 NRF24L01_FLAG |= NRF24L01_AUTO_RX; //发送完是否自动进入接收模式 //NRF24L01_Write_Reg(NRF24L01_WRITE_REG + NRF24L01_SETUP_RETR, 0x25); // [3:0]'0101'-重发5次 [7:4]'0010'-750+86us //NRF24L01_Write_Reg(NRF24L01_WRITE_REG + NRF24L01_RF_CH, 0x00); // [6:0]射频通道(工作频率) //NRF24L01_Write_Reg(NRF24L01_WRITE_REG + NRF24L01_RF_SETUP, 0x0e); // [0]低噪声放大器增益 [2:1]'11'-0dBm [3]'1'-2 Mbps NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_SETUP_AW, NRF24L01_ADR_LEN - 2 ); //设置地址长度为 NRF24L01_ADR_LEN NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_RF_CH, RF_CH ); //设置RF通道为RFCH [6:0] NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_RF_SETUP, 0x07 ); //设置TX发射参数,7db增益,1Mbps,低噪声增益开启 NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_EN_AA, 0x01 ); //使能通道0的自动应答 NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_EN_RXADDR, 0x01 ); //使能通道0的接收地址 //RX模式配置 NRF24L01_Write_Buf ( NRF24L01_WRITE_REG | NRF24L01_RX_ADDR_P0, RX_ADDRESS, NRF24L01_ADR_LEN ); //写RX节点地址 NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_FEATURE, 0x05 ); //使能动态数据包长度,AUTO_ACK模式 NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_DYNPD, 0X01 ); //选择通道0动态数据包长度 NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_FLUSE_RX, NRF24L01_NOP ); //清除RX FIFO寄存器 //TX模式配置 NRF24L01_Write_Buf ( NRF24L01_WRITE_REG | NRF24L01_TX_ADDR , TX_ADDRESS, NRF24L01_ADR_LEN ); //写TX节点地址 NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_SETUP_RETR, 0x1f ); //设置自动重发间隔时间:500us + 86us;最大自动重发次数:15次 NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_FLUSE_TX, NRF24L01_NOP ); //清除TX FIFO寄存器 NRF24L01_RxMode(); //默认进入接收模式 NRF_CE = 1; //NRF24L01_Change_Ch(1); //更改通道0~5 NRF24L01_Interrupt_P03(); } //NRF24L01进入发送模式 void NRF24L01_TxMode ( void ) { NRF_CE = 0; NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_CONFIG, 0x0e ); NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_STATUS, 0x70 ); //清除中断标志 NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_FLUSE_TX, NRF24L01_NOP ); //清除TX FIFO寄存器 NRF_CE = 1; NRF24L01_FLAG &= ~NRF24L01_MODE_RX; //修改状态标识为发射模式 NRF24L01_FLAG &= ~NRF24L01_BUSY; //BUSY标志置0 NRF24L01_FLAG &= ~NRF24L01_RECIVE;//清除有数据标志 } //NRF24L01进入接收模式 void NRF24L01_RxMode ( void ) { NRF_CE = 0; NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_CONFIG, 0x0f ); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式 NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_STATUS, 0x70 ); //清除中断标志 NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_FLUSE_RX, NRF24L01_NOP ); //清除RX FIFO寄存器 NRF_CE = 1; NRF24L01_FLAG |= NRF24L01_MODE_RX; //修改状态标识为接收模式 NRF24L01_FLAG &= ~NRF24L01_BUSY; //BUSY标志置0 DYNPD_LEN = 0; //清0动态数据包长度 NRF24L01_FLAG &= ~NRF24L01_RECIVE;//清除有数据标志 } //NRF24L01 SPI通信检查 void NRF24L01_Check ( void ) { unsigned char i = 0; unsigned char Buff[5]; NRF24L01_Read_Buf ( NRF24L01_TX_ADDR, Buff, NRF24L01_ADR_LEN ); i = NRF24L01_Read_Reg ( NRF24L01_DYNPD ); //读取DYNPD监测是否正确写入 if ( i == 0x01 ) //这里设置的是0x01,要与初始化的值相对应 { for ( i = 0; i < NRF24L01_ADR_LEN; i++ ) { if ( Buff[i] == TX_ADDRESS[i] ) { NRF24L01_FLAG |= NRF24L01_CHECK; } else { NRF24L01_FLAG &= ~NRF24L01_CHECK; break; } } } else NRF24L01_FLAG &= ~NRF24L01_CHECK; } //NRF24L01发送数据 void NRF24L01_SendFrame ( unsigned char *temp, unsigned char len ) { if ( NRF24L01_FLAG & NRF24L01_MODE_RX ) { NRF24L01_TxMode(); } NRF24L01_FLAG |= NRF24L01_BUSY; //BUSY标志置1 NRF24L01_FLAG &= ~NRF24L01_TX_ACCESS;//清除发送成功标志 NRF_CE = 0; if ( NRF24L01_FLAG & NRF24L01_AUTO_ACK ) { NRF24L01_Write_Buf ( NRF24L01_WR_TX_PLOAD, temp, len ); //写待发数据包,需要回应 } else { NRF24L01_Write_Buf ( W_TX_PAYLOAD_NOACK_CMD, temp, len ); //写待发数据包,无须回应 } NRF_CE = 1; } //NRF24L01接收数据 void NRF24L01_RecvFrame ( unsigned char *temp ) { DYNPD_LEN = NRF24L01_Read_Reg ( R_RX_PL_WID_CMD ); if ( DYNPD_LEN > 32 ) { NRF24L01_RxMode(); //重新初始化接收模式 } else { NRF24L01_Read_Buf ( NRF24L01_RD_RX_PLOAD, temp, DYNPD_LEN ); //读取缓冲区数据 } NRF24L01_FLAG &= ~NRF24L01_RECIVE;//清除有数据标志 } //更改RF_CH void NRF24L01_Change_Ch ( unsigned char ch ) { NRF_CE = 0; NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_RF_CH, ch & 0x7F ); //设置RF频道 RF_CH = ch & 0x7F; //同步设置到系统参数 } //NRF24L01中断处理 #ifdef N76E003_IAR #pragma vector=0x3B __interrupt void NRF24L01_Handler ( void ) #else void NRF24L01_Handler ( void ) interrupt 7 //interrupt address is 0x001B #endif { unsigned char state, fifo_state, flag; clr_EPI; //关闭管脚中断7 flag = PIF; PIF = 0x00; //清除全部标志 state = NRF24L01_Read_Reg ( NRF24L01_STATUS ); //读NRF24L01状态寄存器 fifo_state = NRF24L01_Read_Reg ( NRF24L01_FIFO_STATUS ); //读NRF24L01FIFO状态寄存器 NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_STATUS, state ); //清除中断 //发送成功中断 if ( state & NRF24L01_STATUS_TX_DS ) { NRF24L01_FLAG &= ~NRF24L01_BUSY; //BUSY标志置0 NRF24L01_FLAG |= NRF24L01_TX_ACCESS;//发送成功标志置1 if ( NRF24L01_FLAG & NRF24L01_AUTO_RX ) { NRF24L01_RxMode(); //重新初始化接收模式 } } //达到最大重发次数中断 if ( state & NRF24L01_STATUS_MAX_RT ) { NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_FLUSE_TX, NRF24L01_NOP ); //清除TX FIFO寄存器 NRF24L01_FLAG &= ~NRF24L01_BUSY; //BUSY标志置0 NRF24L01_FLAG &= ~NRF24L01_TX_ACCESS;//发送成功标志置0 } //接收到数据中断 if ( state & NRF24L01_STATUS_RX_DR ) { NRF24L01_FLAG |= NRF24L01_RECIVE; //接收到数据标志位置1 } //TX_FIFO满中断 if ( state & NRF24L01_STATUS_TX_FULL ) { NRF24L01_TxMode(); //重新初始化发射模式 } //RX_FIFO满 if ( fifo_state & NRF24L01_STATUS_RX_FULL ) { NRF24L01_RxMode(); //重新初始化接收模式 } state = NRF24L01_Read_Reg ( NRF24L01_STATUS ); //读NRF24L01状态寄存器 set_EPI; //开启管脚中断7 }