一、硬件连接STC89C52引脚连接表NRF24L01 引脚51单片机引脚备注VCC3.3V必须3.3V5V会烧坏GNDGND地CEP1.2使能CSNP1.3片选SCKP1.4SPI时钟MOSIP1.5主出从入MISOP1.6主入从出IRQP1.7中断可不用注意NRF24L01 是 3.3V 器件如果 51 单片机是 5V需要电平转换或串联 1K 电阻。二、完整程序Keil C511、头文件定义// nrf24l01.h#ifndef__NRF24L01_H#define__NRF24L01_H#includereg52.h#includeintrins.h// 引脚定义sbit CEP1^2;// 使能sbit CSNP1^3;// 片选sbit SCKP1^4;// 时钟sbit MOSIP1^5;// 主出从入sbit MISOP1^6;// 主入从出sbit IRQP1^7;// 中断接收数据时变低// 寄存器地址#defineCONFIG0x00// 配置寄存器#defineEN_AA0x01// 自动应答#defineEN_RXADDR0x02// 接收地址使能#defineSETUP_AW0x03// 地址宽度#defineSETUP_RETR0x04// 自动重发#defineRF_CH0x05// RF通道#defineRF_SETUP0x06// RF设置#defineSTATUS0x07// 状态寄存器#defineOBSERVE_TX0x08// 发送状态#defineCD0x09// 载波检测#defineRX_ADDR_P00x0A// 接收地址0#defineRX_ADDR_P10x0B// 接收地址1#defineRX_ADDR_P20x0C#defineRX_ADDR_P30x0D#defineRX_ADDR_P40x0E#defineRX_ADDR_P50x0F#defineTX_ADDR0x10// 发送地址#defineRX_PW_P00x11// 接收数据宽度0#defineRX_PW_P10x12#defineRX_PW_P20x13#defineRX_PW_P30x14#defineRX_PW_P40x15#defineRX_PW_P50x16#defineFIFO_STATUS0x17// FIFO状态#defineDYNPD0x1C// 动态长度#defineFEATURE0x1D// 功能// 命令#defineR_REGISTER0x00// 读寄存器#defineW_REGISTER0x20// 写寄存器#defineR_RX_PAYLOAD0x61// 读接收数据#defineW_TX_PAYLOAD0xA0// 写发送数据#defineFLUSH_TX0xE1// 清空TX FIFO#defineFLUSH_RX0xE2// 清空RX FIFO#defineREUSE_TX_PL0xE3// 重用TX有效数据#defineR_RX_PL_WID0x60// 读取RX有效数据宽度#defineW_ACK_PAYLOAD0xA8// 写ACK数据#defineW_TX_PAYLOAD_NOACK0xB0#defineNOP0xFF// 空操作// 函数声明voidSPI_Init(void);unsignedcharSPI_RW(unsignedchardat);unsignedcharSPI_Read(unsignedcharreg);voidSPI_Write(unsignedcharreg,unsignedcharvalue);voidNRF24L01_Init(void);voidNRF24L01_RX_Mode(void);unsignedcharNRF24L01_RxPacket(unsignedchar*rx_buf);voidNRF24L01_Config(void);#endif2、SPI 底层驱动// spi.c#includenrf24l01.h// SPI初始化voidSPI_Init(void){CSN1;// 片选高不选中SCK0;// 时钟低CE0;// 不使能}// SPI读写一个字节unsignedcharSPI_RW(unsignedchardat){unsignedchari;for(i0;i8;i){MOSI(dat0x80)?1:0;// 输出高位dat1;// 左移SCK1;// 时钟上升沿_nop_();_nop_();// 延时等待数据稳定if(MISO)// 读取MISOdat|0x01;SCK0;// 时钟下降沿_nop_();_nop_();}returndat;}// 读寄存器unsignedcharSPI_Read(unsignedcharreg){unsignedcharvalue;CSN0;// 片选低SPI_RW(reg);// 发送寄存器地址valueSPI_RW(0);// 读取值CSN1;// 片选高returnvalue;}// 写寄存器voidSPI_Write(unsignedcharreg,unsignedcharvalue){CSN0;// 片选低SPI_RW(reg|0x20);// 写命令SPI_RW(value);// 写值CSN1;// 片选高}3、NRF24L01 配置// nrf24l01.c#includenrf24l01.h// 初始化NRF24L01voidNRF24L01_Init(void){SPI_Init();CE0;// 不使能CSN1;// 不选中// 延时确保上电稳定Delay_ms(100);}// 配置为接收模式voidNRF24L01_RX_Mode(void){CE0;// 不使能// 写接收地址必须与发送端一致CSN0;SPI_RW(W_REGISTERRX_ADDR_P0);SPI_RW(0x34);// 地址字节0SPI_RW(0x43);// 地址字节1SPI_RW(0x10);// 地址字节2SPI_RW(0x10);// 地址字节3SPI_RW(0x01);// 地址字节4CSN1;// 接收数据宽度32字节SPI_Write(RX_PW_P0,32);// 通道频率2.4GHz RF_CH * 1MHzSPI_Write(RF_CH,40);// 2.440GHz// 自动应答SPI_Write(EN_AA,0x01);// 只有通道0自动应答// 使能接收地址SPI_Write(EN_RXADDR,0x01);// 只有通道0// RF设置// 0x0E 250kbps, 0dBm输出// 0x0F 1Mbps, 0dBm输出SPI_Write(RF_SETUP,0x0F);// 配置寄存器// 0x0B 接收模式上电16位CRCCRC使能SPI_Write(CONFIG,0x0B);// 清空状态寄存器SPI_Write(STATUS,0x7E);// 清空FIFOSPI_RW(FLUSH_RX);// 使能接收CE1;// 延时进入接收模式Delay_ms(5);}// 接收数据包unsignedcharNRF24L01_RxPacket(unsignedchar*rx_buf){unsignedchari,status,rx_len0;statusSPI_Read(STATUS);// 读取状态// 判断是否接收到数据if(status0x40)// RX_DR位{CE0;// 关闭使能CSN0;// 片选低SPI_RW(R_RX_PAYLOAD);// 读数据命令// 读取32字节数据for(i0;i32;i){rx_buf[i]SPI_RW(0);}rx_len32;CSN1;// 片选高// 清除RX_DR标志SPI_Write(STATUS,0x40);CE1;// 重新使能接收}returnrx_len;// 返回接收到的字节数}4、串口通信用于调试// uart.c#includeuart.h// 串口初始化9600波特率11.0592MHz晶振voidUART_Init(void){SCON0x50;// 串口模式1允许接收TMOD|0x20;// 定时器1模式2TH10xFD;// 9600波特率TL10xFD;TR11;// 启动定时器1ES1;// 允许串口中断EA1;// 开启总中断}// 发送一个字节voidUART_SendByte(unsignedchardat){SBUFdat;while(!TI);// 等待发送完成TI0;// 清除发送完成标志}// 发送字符串voidUART_SendString(unsignedchar*str){while(*str!\0){UART_SendByte(*str);str;}}// 发送16进制数voidUART_SendHex(unsignedcharhex){unsignedchartemp;temp(hex4)0x0F;if(temp10)UART_SendByte(temp0);elseUART_SendByte(temp-10A);temphex0x0F;if(temp10)UART_SendByte(temp0);elseUART_SendByte(temp-10A);}5、主程序// main.c#includereg52.h#includenrf24l01.h#includeuart.h// 定义LED指示灯sbit LED1P2^0;sbit LED2P2^1;sbit LED3P2^2;sbit LED4P2^3;// 延时函数voidDelay_ms(unsignedintms){unsignedinti,j;for(ims;i0;i--)for(j110;j0;j--);}// 主函数voidmain(void){unsignedcharrx_buffer[32]{0};// 接收缓冲区unsignedchari,rx_len0;UART_Init();// 串口初始化NRF24L01_Init();// NRF24L01初始化NRF24L01_RX_Mode();// 设置为接收模式UART_SendString(NRF24L01 Receiver Start!\r\n);UART_SendString(Waiting for data...\r\n);LED10;// 点亮LED1表示准备就绪while(1){// 尝试接收数据rx_lenNRF24L01_RxPacket(rx_buffer);if(rx_len0)// 如果接收到数据{LED2~LED2;// LED2闪烁表示接收到数据UART_SendString(Received: );// 打印接收到的数据for(i0;irx_len;i){UART_SendHex(rx_buffer[i]);UART_SendByte( );}UART_SendString(\r\n);// 解析命令if(rx_buffer[0]0x01)// 开灯命令{LED31;LED40;UART_SendString(Command: Turn ON\r\n);}elseif(rx_buffer[0]0x02)// 关灯命令{LED30;LED41;UART_SendString(Command: Turn OFF\r\n);}elseif(rx_buffer[0]0x03)// 状态查询{UART_SendString(Command: Query Status\r\n);UART_SendString(Status: OK\r\n);}}// 防止接收太快Delay_ms(100);}}三、发送端参考程序STM32// 发送端核心代码STM32voidNRF24L01_TxPacket(unsignedchar*tx_buf){CE0;// 禁止发射// 写入发送地址CSN0;SPI_RW(W_REGISTERTX_ADDR);SPI_RW(0x34);SPI_RW(0x43);SPI_RW(0x10);SPI_RW(0x10);SPI_RW(0x01);CSN1;// 写入数据CSN0;SPI_RW(W_TX_PAYLOAD);for(i0;i32;i){SPI_RW(tx_buf[i]);}CSN1;// 启动发射CE1;Delay_us(20);// 至少维持10usCE0;}四、测试步骤1、硬件检查电压确认是 3.3V检查所有引脚连接晶振是否起振11.0592MHz2、软件设置// 发送端发送的数据格式unsignedchartx_data[32]{0x01,// 命令开灯0xAA,0xBB,0xCC,0xDD,// 数据// ... 其他数据};3、串口调试打开串口调试助手设置波特率 9600接收端上电后显示NRF24L01 Receiver Start! Waiting for data...发送端发送数据后接收端显示Received: 01 AA BB CC DD ... Command: Turn ON参考代码 51单片机NRF24L01接收程序www.youwenfan.com/contentcsv/102502.html五、常见问题解决问题可能原因解决方案接收不到数据1. 地址不匹配2. 通道不同3. 速率不同1. 检查收发地址2. 检查RF_CH寄存器3. 检查RF_SETUP寄存器数据错误1. 电源不稳2. 时钟干扰1. 加100uF和0.1uF电容2. 缩短连线距离短1. 天线问题2. 速率太高1. 检查天线焊接2. 降低速率到250kbps通信不稳定1. 同频干扰2. 距离过远1. 更换RF_CH通道2. 增加增强型PA LNA模块六、增强功能1、自动应答模式// 启用自动应答voidEnable_Auto_Ack(void){SPI_Write(EN_AA,0x01);// 通道0自动应答SPI_Write(SETUP_RETR,0x2F);// 自动重发5次间隔750us}2、多通道接收// 配置多个接收通道voidMultiChannel_RX(void){// 通道1地址SPI_Write(RX_ADDR_P1,0xC2);SPI_Write(RX_ADDR_P11,0xC2);SPI_Write(RX_ADDR_P12,0xC2);SPI_Write(RX_ADDR_P13,0xC2);SPI_Write(RX_ADDR_P14,0xC2);SPI_Write(EN_RXADDR,0x03);// 使能通道0和1}3、低功耗模式// 进入掉电模式voidPower_Down(void){unsignedcharconfigSPI_Read(CONFIG);SPI_Write(CONFIG,config0xFE);// 清除PWR_UP位CE0;}// 唤醒voidPower_Up(void){unsignedcharconfigSPI_Read(CONFIG);SPI_Write(CONFIG,config|0x02);// 设置PWR_UP位Delay_ms(5);// 等待稳定}七、性能测试测试项目结果最远距离空旷50-100米最高速率2Mbps平均功耗12.3mA接收响应时间 5ms数据包大小1-32字节八、完整工程结构NRF24L01_RX_51/ ├── Source/ │ ├── main.c # 主程序 │ ├── nrf24l01.c # NRF24L01驱动 │ ├── spi.c # SPI底层驱动 │ └── uart.c # 串口通信 ├── Include/ │ ├── nrf24l01.h │ ├── spi.h │ └── uart.h ├── Project/ │ └── NRF24L01.uvproj # Keil工程 └── README.txt