基于STM32F103的NRF24L01无线通信模块的使用心得

一、硬件选型

        1,stm32f103c8t6最小系统板

        2,NRF24L01无线通信模块

        3,OLED屏(看效果用)

        4,USB转TTL

        5,杜邦线若干

        6,一个丁老头

二、硬件接线

        发送端、接收端一样

                

 三、程序编写

  1,NRF初始化

void NRF24L01_Gpio_Init( void )
{
	GPIO_InitTypeDef	RF24L01_GpioInitStructer;
	
	RCC_APB2PeriphClockCmd( RF24L01_CE_GPIO_CLK | RF24L01_IRQ_GPIO_CLK, ENABLE );
	
	RF24L01_GpioInitStructer.GPIO_Mode = GPIO_Mode_Out_PP;
	RF24L01_GpioInitStructer.GPIO_Speed = GPIO_Speed_10MHz;
	RF24L01_GpioInitStructer.GPIO_Pin = RF24L01_CE_GPIO_PIN;
	GPIO_Init( RF24L01_CE_GPIO_PORT, &RF24L01_GpioInitStructer );
	GPIO_SetBits( RF24L01_CE_GPIO_PORT, RF24L01_CE_GPIO_PIN);
	
	RF24L01_GpioInitStructer.GPIO_Mode = GPIO_Mode_IPU;
	RF24L01_GpioInitStructer.GPIO_Speed = GPIO_Speed_10MHz;
	RF24L01_GpioInitStructer.GPIO_Pin = RF24L01_IRQ_GPIO_PIN;
	GPIO_Init( RF24L01_IRQ_GPIO_PORT, &RF24L01_GpioInitStructer );

	GPIO_SetBits( RF24L01_IRQ_GPIO_PORT, RF24L01_IRQ_GPIO_PIN);
	
	RF24L01_SET_CE_LOW( );
	RF24L01_SET_CS_HIGH( );
}

2,NRF工作模式配置

void RF24L01_Set_Mode( nRf24l01ModeType Mode )
{
    uint8_t controlreg = 0;
	controlreg = NRF24L01_Read_Reg( CONFIG );
	
    if( Mode == MODE_TX )       
	{
		controlreg &= ~( 1<< PRIM_RX );
	}
    else 
	{
		if( Mode == MODE_RX )  
		{ 
			controlreg |= ( 1<< PRIM_RX ); 
		}
	}

    NRF24L01_Write_Reg( CONFIG, controlreg );
}

 3,NRF数据发送

uint8_t NRF24L01_TxPacket( uint8_t *txbuf, uint8_t Length )
{
	uint8_t l_Status = 0;
	uint16_t l_MsTimes = 0;
	RF24L01_SET_CS_LOW( );		//片选
	drv_spi_read_write_byte( FLUSH_TX );
	RF24L01_SET_CS_HIGH( );
	RF24L01_SET_CE_LOW( );		
	NRF24L01_Write_Buf( WR_TX_PLOAD, txbuf, Length );	//写数据到TX BUF 32字节  TX_PLOAD_WIDTH
	RF24L01_SET_CE_HIGH( );			//启动发送
	while( 0 != RF24L01_GET_IRQ_STATUS( ))
	{
		delay_ms( 1 );
		if( 500 == l_MsTimes++ )						//500ms还没有发送成功,重新初始化设备
		{
			NRF24L01_Gpio_Init( );
			RF24L01_Init( );
			RF24L01_Set_Mode( MODE_TX );
			break;
		}
	}
	l_Status = NRF24L01_Read_Reg(STATUS);						//读状态寄存器
	NRF24L01_Write_Reg( STATUS, l_Status );						//清除TX_DS或MAX_RT中断标志
	
	if( l_Status & MAX_TX )	//达到最大重发次数
	{
		NRF24L01_Write_Reg( FLUSH_TX,0xff );	//清除TX FIFO寄存器
		return MAX_TX; 
	}
	if( l_Status & TX_OK )	//发送完成
	{
		return TX_OK;
	}
	return 0xFF;	//其他原因发送失败
}

4,NRF数据接收

uint8_t NRF24L01_RxPacket( uint8_t *rxbuf )
{
	uint8_t l_Status = 0, l_RxLength = 0, l_100MsTimes = 0;
	
	RF24L01_SET_CS_LOW( );		//片选
	drv_spi_read_write_byte( FLUSH_RX );
	RF24L01_SET_CS_HIGH( );
	
	while( 0 != RF24L01_GET_IRQ_STATUS( ))
	{
		delay_ms( 100 );
		
		if( 30 == l_100MsTimes++ )		//3s没接收过数据,重新初始化模块
		{
			NRF24L01_Gpio_Init( );
			RF24L01_Init( );
			RF24L01_Set_Mode( MODE_RX );
			break;
		}
	}
	
	l_Status = NRF24L01_Read_Reg( STATUS );		//读状态寄存器
	NRF24L01_Write_Reg( STATUS,l_Status );		//清中断标志
	if( l_Status & RX_OK)	//接收到数据
	{
		l_RxLength = NRF24L01_Read_Reg( R_RX_PL_WID );		//读取接收到的数据个数
		NRF24L01_Read_Buf( RD_RX_PLOAD,rxbuf,l_RxLength );	//接收到数据 
		NRF24L01_Write_Reg( FLUSH_RX,0xff );				//清除RX FIFO
		return l_RxLength; 
	}	
	
	return 0;				//没有收到数据	
}

5.1,发送端主函数

int main(void)
{  	
	    uint8_t num,i;
		delay_init();	    	 //延时函数初始化	  
		OLED_Init();			//初始化OLED  
		OLED_Clear();
	    
	    drv_spi_init();
	    NRF24L01_Gpio_Init();     //RF24L01引脚初始化
	    NRF24L01_check();	 //检测nRF24L01		
        RF24L01_Init();

		OLED_Clear();
		OLED_ShowCHinese(0,3,0);     //发
		OLED_ShowCHinese(18,3,1);    //送
		OLED_ShowCHinese(36,3,2);    //次
		OLED_ShowCHinese(54,3,3);    //数
		OLED_ShowCHinese(72,3,4);    //:
		
		while(1)
		{
			for(i = 0; i < 54;i++)
			{
				RF24L01_Set_Mode(MODE_TX);		//发送模式
				NRF24L01_TxPacket(BMP1+i*20 ,20);		//模式1发送固定字符,1S一包
				//BMP1是我自己生成的一个丁老头文件
				OLED_ShowNum(0,6,num,15,12);
				num++;
				delay_ms(50);
			}
//			OLED_DrawBMP(32,1,127,7,BMP2);
		}
}  

5.2,接收端主函数

int main(void)
{  	
	
	delay_init();	    	 //延时函数初始化	 
	OLED_Init();			//初始化OLED  
	OLED_Clear();
	    
	drv_spi_init();
	NRF24L01_Gpio_Init();     //RF24L01引脚初始化
	NRF24L01_check();	 //检测nRF24L01		
    RF24L01_Init();
	
	OLED_Clear();
    OLED_ShowCHinese(0,2,0);     //接
	OLED_ShowCHinese(18,2,1);    //收
	OLED_ShowCHinese(36,2,2);    //数
	OLED_ShowCHinese(54,2,3);    //据
	delay_ms(1000);
	
	while(1)
	{
		for(i = 0; i <= 8;i++)
		{
			RF24L01_Set_Mode(MODE_RX);		//接收模式
			j = NRF24L01_RxPacket(RF24L01RxBuffer);	//接收字节
			
			if((RF24L01RxBuffer[0] == 0x7f) && flag_fir == 0 )	//验校接收针头
			{
				i = 0;flag_fir = 1;
			}
			else if(flag_fir == 1)	//接收数据
			{
				if(j != 0)	//检验非空
				{
					num_las+=j;
					
					for(num = 0;num < j; num++)
					{	
						nrf24L01_data[num_las] = RF24L01RxBuffer[num];
					}
					OLED_DrawBMP(x,y,120,7,RF24L01RxBuffer);
					x+=20;
					if(x > 120)
					{
						x=0;y++;
					}
				}
				else
				{
					OLED_Clear();
					OLED_ShowString(1,1,"error",16);
					flag_fir = 0;num_las = 0;y = 0;x = 0;
				}
			}
		}
	}
}

四、实验结果

五、不足

        1,接收速率低,如果出现丢包就要重新等待新的数据帧头到

        2,接收时间长,我的代码问题

六,后续发展

        我的问题在ZE里完美解决,可以配合摄像头OV7670拍照并传输图像数据给接收端,大概7~10秒出一帧图像,如果硬件到位可以做成视频流,没法给大家视频展示了,因为上交了。。。

本次的分享就到这,欢迎大佬们观看,如有问题可私聊我,看到就回。

思路来源:STM32无线通信——nRF24L01通信模块_nrf24l01无线通信实验_Mannixcsdn的博客-CSDN博客

  • 7
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值