一、硬件选型
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博客