51驱动NRF24L01通信,NRF24L01与TTL转NRF24L01模块通信

51驱动NRF24L01通信,NRF24L01与TTL转NRF24L01模块通信

  • NRF24L01
  • 一、简介
  • 二、引脚功能描述
  • 程序设计
  • 一、对 24L01 的程序编程的基本思路如下:
  • 二、Tx 与 Rx 的配置过程
  • 1、Tx 模式初始化过程:
  • 2、Rx 模式初始化过程:
  • 三、基本程序函数
  • 通信测试
  • 一、两个51单片机控制NRF24L01互相通信
  • 一、51单片机控制NRF24L01与NRF24L01转TTL串口模块通信
  • 总结
  • NRF24L01

    一、简介

    NRF24L01 是 NORDIC 公司最近生产的一款无线通信通信芯片,采用 FSK 调制,内部
    集成 NORDIC 自己的 Enhanced Short Burst 协议。可以实现点对点或是 1 对 6 的无线通信。无线通信速度可以达到 2M(bps)。NORDIC 公司提供通信模块的 GERBER 文件,可以直接加工生产。嵌入式工程师或是单片机爱好者只需要为单片机系统预留 5 个 GPIO,1 个中断输入引脚,就可以很容易实现无线通信的功能,非常适合用来为 MCU 系统构建无线通信功能。

    二、引脚功能描述


    VCC 脚接电压范围为2.0V~3.6V 之间,不能在这个区间之外,超过 3.6V 将会烧毁模块。推荐电压 3.3V 左右。除电源 VCC 和接地端,其余脚都可以直接和普通的 5V 单片机 IO口直接相连,无需电平转换。当然对3V左右的单片机更加适用了。

    程序设计

    一、对 24L01 的程序编程的基本思路如下:

    1) 置 CSN 为低,使能芯片,配置芯片各个参数。(过程见 3.Tx 与 Rx 的配置过程)
    配置参数在 Power Down 状态中完成。
    2) 如果是 Tx 模式,填充 Tx FIFO。
    3) 配置完成以后,通过 CE 与 CONFIG 中的 PWR_UP 与 PRIM_RX 参数确定 24L01
    要切换到的状态。
    Tx Mode:PWR_UP=1; PRIM_RX=0; CE=1 (保持超过 10us 就可以);
    Rx Mode: PWR_UP=1; PRIM_RX=1; CE=1;
    4) IRQ 引脚会在以下三种情况变低:
    Tx FIFO 发完并且收到 ACK(使能 ACK 情况下)
    Rx FIFO 收到数据
    达到最大重发次数
    将 IRQ 接到外部中断输入引脚,通过中断程序进行处理。

    二、Tx 与 Rx 的配置过程

    1、Tx 模式初始化过程:

    1)写 Tx 节点的地址 TX_ADDR
    2)写 Rx 节点的地址(主要是为了使能 Auto Ack) RX_ADDR_P0
    3)使能 AUTO ACK EN_AA
    4)使能 PIPE 0 EN_RXADDR
    5)配置自动重发次数 SETUP_RETR
    6)选择通信频率 RF_CH
    7)配置发射参数(低噪放大器增益、发射功率、无线速率) RF_SETUP
    8 ) 选择通道 0 有效数据宽度 Rx_Pw_P0
    9)配置 24L01 的基本参数以及切换工作模式 CONFIG。

    2、Rx 模式初始化过程:

    1)写 Rx 节点的地址 RX_ADDR_P0
    2)使能 AUTO ACK EN_AA
    3)使能 PIPE 0 EN_RXADDR
    4)选择通信频率 RF_CH
    5) 选择通道 0 有效数据宽度 Rx_Pw_P0
    6)配置发射参数(低噪放大器增益、发射功率、无线速率) RF_SETUP
    7)配置 24L01 的基本参数以及切换工作模式 CONFIG。

    三、基本程序函数

    下面主要介绍几个重要程序函数,其它的程序函数需要的可以留言获取
    1、nRF24L01+接收模式初始化

    void nRF24L01P_RX_Mode(void)
    {
    	CE = 0;
    	nRF24L01P_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);  // 接收设备接收通道0使用和发送设备相同的发送地址
    	nRF24L01P_Write_Reg(WRITE_REG + EN_AA, 0x01);               			// 使能接收通道0自动应答
    	nRF24L01P_Write_Reg(WRITE_REG + EN_RXADDR, 0x01);           	    	// 使能接收通道0
    	nRF24L01P_Write_Reg(WRITE_REG + RF_CH, 40);                 			// 选择射频通道0x40
    	nRF24L01P_Write_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH);  		    // 接收通道0选择和发送通道相同有效数据宽度
    	nRF24L01P_Write_Reg(WRITE_REG + RF_SETUP, 0x0f);            			// 数据传输率2Mbps,发射功率0dBm,低噪声放大器增益(nRF24L01+忽略该位)
    	nRF24L01P_Write_Reg(WRITE_REG + CONFIG, 0x0f);              			// CRC使能,16位CRC校验,上电,接收模式
    	nRF24L01P_Write_Reg(WRITE_REG + STATUS, 0xff);  						//清除所有的中断标志位
    	CE = 1;                                            						// 拉高CE启动接收设备
    }		
    

    2、nRF24L01+发送模式初始化

    void nRF24L01P_TX_Mode(void)
    {
    	CE = 0;
    	nRF24L01P_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);     // 写入发送地址
    	nRF24L01P_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);  // 为了应答接收设备,接收通道0地址和发送地址相同
    
    	nRF24L01P_Write_Reg(WRITE_REG + EN_AA, 0x01);       					// 使能接收通道0自动应答
    	nRF24L01P_Write_Reg(WRITE_REG + EN_RXADDR, 0x01);   					// 使能接收通道0
    	nRF24L01P_Write_Reg(WRITE_REG + SETUP_RETR, 0x0a);  					// 自动重发延时等待250us+86us,自动重发10次
    	nRF24L01P_Write_Reg(WRITE_REG + RF_CH, 40);         					// 选择射频通道0x40
    	nRF24L01P_Write_Reg(WRITE_REG + RF_SETUP, 0x0f);    					// 数据传输率2Mbps,发射功率0dBm,低噪声放大器增益(nRF24L01+忽略该位)
    	nRF24L01P_Write_Reg(WRITE_REG + CONFIG, 0x0e);     					    // CRC使能,16位CRC校验,上电
    	//CE = 1;
    }
    

    3、

    /********************************************************
    函数功能:读取接收数据                       
    入口参数:rxbuf:接收数据存放首地址
    返回  值:0:接收到数据
              1:没有接收到数据
    *********************************************************/
    u8 nRF24L01P_RxPacket(u8 *rxbuf)
    {
    	u8 stat
    	state = nRF24L01P_Read_Reg(STATUS);  			              //读取状态寄存器的值    	  
    	nRF24L01P_Write_Reg(WRITE_REG+STATUS,state);                  //清除RX_DS中断标志
    
    	if(state & RX_DR)								              //接收到数据
    	{
    		nRF24L01P_Read_Buf(RD_RX_PLOAD,rxbuf,TX_PLOAD_WIDTH);     //读取数据
    		nRF24L01P_Write_Reg(FLUSH_RX,0xff);					      //清除RX FIFO寄存器
    		return 0; 
    	}	   
    	return 1;                                                     //没收到任何数据
    }
    

    4、

    /********************************************************
    函数功能:发送一个数据包                      
    入口参数:txbuf:要发送的数据
    返回  值:0x10:达到最大重发次数,发送失败 
              0x20:发送成功            
              0xff:发送失败                  
    *********************************************************/
    u8 nRF24L01P_TxPacket(u8 *txbuf)
    {
    	u8 state;
    	CE=0;													//CE拉低,使能24L01配置
      nRF24L01P_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);	//写数据到TX FIFO,32个字节
     	CE=1;		    									    //CE置高,使能发送	   
    	
    	while(IRQ == 1);										//等待发送完成
    	state=nRF24L01P_Read_Reg(STATUS);  						//读取状态寄存器的值	   
    	nRF24L01P_Write_Reg(WRITE_REG+STATUS,state); 			//清除TX_DS或MAX_RT中断标志
    	if(state&MAX_RT)			   						    //达到最大重发次数
    	{
    		nRF24L01P_Write_Reg(FLUSH_TX,0xff);					//清除TX FIFO寄存器 
    		return MAX_RT; 
    	}
    	if(state&TX_DS)									        //发送完成
    	{
    		return TX_DS;
    	}
    	return 0XFF;	 									    //发送失败
    }
    

    通信测试

    1、两个NRF24L01的目标地址和接收地址需要设置成一样的,
    发送和接收程序下面这个函数里面的地址必须是一样的

    u8 code TX_ADDRESS[TX_ADR_WIDTH] = {0x11,0x22,0x33,0x44,0x55};  // 定义一个静态发送地址
    

    2、通信频率需要设置成一样的,RF_CH是选择频率寄存器,
    频率计算公式是2400+“RF_CH”,单位是MHZ;接收和发射函数里面设置的RF_CH值是40,所以实际通信频率是2400+40=2.440GHZ
    3、数据传输速率也需要设置成一样的,

    一、两个51单片机控制NRF24L01互相通信

    1、51单片机和NRF24L01接线

    STC89C52RC NRF24L01
    VCC 3.3V
    GND GND
    CSN P1_5
    CE P1_4
    MOSI P1_3
    SCK P1_2
    IRQ P1_1
    MISO P1_0

    2、发送程序

    u8 a = 0;
    
    int main(void)
    {
    	UART_Init();
    	nRF24L01P_Init();
    	while(1)
    	{
    		u8 buf[32] = {0};
    		buf[0] = 0xAA;
    		nRF24L01P_TX_Mode();
    		a = nRF24L01P_TxPacket(buf);
    		Delay(200);
    		UART_SendByte(a);
    		buf[0] = 0;
    	}
    }
    

    3、接收程序

    int main(void)
    {
    	u8 buf[32] = {0};
    	nRF24L01P_Init();
    	UART_Init();
    	nRF24L01P_RX_Mode();
    	while(1)
    	{
    		buf[0] = 0;
    		nRF24L01P_RxPacket(buf);
    		UartSendStr(buf);
    		Delay(200);
    		buf[0] = 0;
    	}
    }
    

    实验现象

    下图,右边的20是发送成功标志,左边AA是发送的数据

    一、51单片机控制NRF24L01与NRF24L01转TTL串口模块通信

    1、NRF24L01转TTL串口模块

    接收参数和发射参数需要设置成一样的才能通讯

    2、发射程序

    int a = 0;
    
    int main(void)
    {
    	UART_Init();
    	nRF24L01P_Init();	
    	while(1)
    	{
    		u8 buf[32] = {" NRF24L01 Test\r\n"};
    		nRF24L01P_TX_Mode();
    		a = nRF24L01P_TxPacket(buf);
    		UART_SendByte(a);
    		Delay(200);
    	}
    }
    

    3、现象

    总结

    NRF24L01模块不支持热插拔,热插拔会损坏模块;代码调试的过程还有些小BUG,希望得到大佬指点,需要工程的在下方留言

    物联沃分享整理
    物联沃-IOTWORD物联网 » 51驱动NRF24L01通信,NRF24L01与TTL转NRF24L01模块通信

    发表评论