HAL库串口接收定长数据包,数据有结尾标志。

复杂安全的实现:有帧尾,无帧头,有超时时间 的定长数据包。

(数据以’\0’为结尾标志,发送和接收速度为115200Bit/s,超时时间需要根据数据慢慢调)

串口中断:

/***********		WIFI提示信息接收 相关  *******************/

	uint8_t USART1_Receive_message [50]={0};
	uint8_t Receive_Number=0;//一次性接收了多少个数据
	uint8_t Receive_times=0;//接收信息次数
	uint8_t USART1_Receive_message_buffer [1]={0};//一次接收一个
	
/*********************************************************/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
			if(huart->Instance==USART1)//WIFI打印提示信息
		{
		if(Menus_Deep==3)//如果在模式WIFI里面
		{
			if(USART1_Receive_message_buffer[0]!='\n')//如果没有接收结束。
			{
				/***********	启动定时器TIM2中断,开始计时 time out	****************************/
				__HAL_TIM_CLEAR_IT(&htim2 ,TIM_IT_UPDATE ); 
				HAL_TIM_Base_Start_IT(&htim2 );               
				/******************************************************************************/
				USART1_Receive_message[Receive_Number]=USART1_Receive_message_buffer[0];
				Receive_Number++;
			}
			else //如果接收结束
			{
				/***********	启动定时器TIM2中断,结束计时 time out	****************************/
				__HAL_TIM_CLEAR_IT(&htim2 ,TIM_IT_UPDATE ); 
				HAL_TIM_Base_Stop_IT(&htim2 );               
				/******************************************************************************/
					if(Receive_times>8) //如果要显示的数据超出显示边界,刷屏
					{
						LCD_Fill(65,27,320-5,190,BLACK);
						Receive_times=0;
					}
				if(Menus_Deep==3)//如果在模式WIFI里面
				Show_Str(65+1,27+Receive_times*16,RED,BLACK,(char *)USART1_Receive_message,16,0);//把接收区里的全部数据显示出来
				memset(USART1_Receive_message, 0, sizeof(USART1_Receive_message));//清空接收区数据
				Receive_times++;//接收的次数+1
				Receive_Number=0;		
			}
		}
		HAL_UART_Receive_IT(&huart1,USART1_Receive_message_buffer, 1);
	}
}

//定时器中断:
	if(htim->Instance==TIM2) //定时器中断   10ms 中断一次 串口接收数据超时
	{	
		memset(USART1_Receive_message, 0, sizeof(USART1_Receive_message));//清空接收区数据
		Receive_Number=0;
	}

简单实现:无超时时间 的定长数据包(自己确定数据量大小):

(以0XF0开头,0X0F结尾,发送和接收速度为115200Bit/s)
/*********************	WIFI 数据发送和接收 相关 ****************************************/
uint8_t USART_Receive_buff[7]={0xf0,0x01,0x02,0x03,0x04,0x05,0x0f}; //接收帧格式		0xf0为帧头,0x0f为帧尾
uint8_t USART_Receive_Onebyte [1]={0};

/******************************************************************************************/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	static uint8_t Receive_Number=0;//一次性接收了多少个数据
	static bool Receive_enable=false;//是否使能接收数据
	 if(huart->Instance==USART2)
		{
			
				if(USART_Receive_Onebyte[0]==0xf0 )//如果收到了帧头:
				{
					Receive_enable=true;	//使能接收
					Receive_Number=0;//从第零位开始接收。
					memset(USART_Receive_buff, 0, sizeof(USART_Receive_buff));//清空接收区数据
				}
				else if(USART_Receive_Onebyte[0]==0x0f)//如果收到了帧尾:
				{
					USART_Receive_buff[Receive_Number]=USART_Receive_Onebyte[0];//将帧尾放进去后,再使能接收
					
					Receive_enable=false;//失能接收
					Receive_Number=0;//清零接收位。
					//memset(USART_Receive_buff, 0, sizeof(USART_Receive_buff));//清空接收区数据  接收结束后千万不能清空,不然数据就没了。。。。					
				}	
				if(Receive_enable==true)//如果接收被使能,开始接收数据
				{
					USART_Receive_buff[Receive_Number]=USART_Receive_Onebyte[0];
					Receive_Number++;
				}	
				
		  HAL_UART_Receive_IT(&huart2, USART_Receive_Onebyte, 1);//开启下一次接收中断
		}
}

定长数据包 2021.8.1更新

#define USART1_Receive_Size 7
uint8_t USART1_Camera_Receive_buff[7]={0x00}; 
uint8_t USART1_Receive_Onebyte [1]={0};
	
		if(huart->Instance==USART1)
		{
				static uint8_t USART1_Receive_buff[USART1_Receive_Size]={0x00}; 
				static uint8_t Uart1_Receive_Number=0;//一次性接收了多少个数据
				static bool Uart1_Receive_enable=false;//是否使能接收数据
			
				if(USART1_Receive_Onebyte[0]==0xf0 )//如果收到了帧头:
				{
					Uart1_Receive_enable=true;	//使能接收
					Uart1_Receive_Number=0;//从第零位开始接收。
					memset(USART1_Receive_buff, 0, sizeof(USART1_Receive_buff));//清空接收区数据
				}
				else if(USART1_Receive_Onebyte[0]==0x0f && Uart1_Receive_Number==USART1_Receive_Size-1)//如果收到了帧尾,并且数据长度正常。
				{
//						uint8_t i,AddCheck=0;
//						for(i=0;i<USART1_Receive_Size-3;i++)
//						{
//							AddCheck+=USART1_Receive_buff[i+1];
//						}
//						AddCheck&=0xff;
//					
//						if(USART1_Receive_buff[USART1_Receive_Size-2]==AddCheck)  //和校验
						{
							USART1_Receive_buff[Uart1_Receive_Number]=USART1_Receive_Onebyte[0];//将帧尾放进去后,再使能接收
							Uart1_Receive_enable=false;//失能接收
							Uart1_Receive_Number=0;//清零接收位。

							memcpy(USART1_Camera_Receive_buff,USART1_Receive_buff,sizeof(USART1_Receive_buff));
							
							Camera_Ball_X=USART1_Camera_Receive_buff[1]*256+USART1_Camera_Receive_buff[2];
							Camera_Ball_Y=USART1_Camera_Receive_buff[3]*256+USART1_Camera_Receive_buff[4];
							
						}
				}	
				if(Uart1_Receive_enable==true)//如果接收被使能,开始接收数据
				{
					USART1_Receive_buff[Uart1_Receive_Number]=USART1_Receive_Onebyte[0];
					Uart1_Receive_Number++;
				}	
			HAL_UART_Receive_IT(&huart1, USART1_Receive_Onebyte, 1);//开启下一次接收中断
		}
	 if(huart->Instance==USART2)
		{				
				static uint8_t Uart2_Receive_Number=0;//一次性接收了多少个数据
				static bool Uart2_Receive_enable=false;//是否使能接收数据


			
				if(USART2_Receive_Onebyte[0]==0xf0 )//如果收到了帧头:
				{
					Uart2_Receive_enable=true;	//使能接收
					Uart2_Receive_Number=0;//从第零位开始接收。
					memset(USART2_Agreement_Receive_buff, 0, sizeof(USART2_Agreement_Receive_buff));//清空接收区数据
				}
				else if(USART2_Receive_Onebyte[0]==0x0f)//如果收到了帧尾:
				{
					USART2_Agreement_Receive_buff[Uart2_Receive_Number]=USART2_Receive_Onebyte[0];//将帧尾放进去后,再使能接收
					
					Uart2_Receive_enable=false;//失能接收
					Uart2_Receive_Number=0;//清零接收位。
		
					
				HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
				HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);		
				__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_1,USART2_Agreement_Receive_buff[1]); //50-250  500us-2500us 
				__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_2,USART2_Agreement_Receive_buff[2]);
		
					
					//memset(USART2_Agreement_Receive_buff, 0, sizeof(USART2_Agreement_Receive_buff));//清空接收区数据  接收结束后千万不能清空,不然数据就没了。。。。					
				}	
				if(Uart2_Receive_enable==true)//如果接收被使能,开始接收数据
				{
					USART2_Agreement_Receive_buff[Uart2_Receive_Number]=USART2_Receive_Onebyte[0];
					Uart2_Receive_Number++;
				}	
				
		  HAL_UART_Receive_IT(&huart2, USART2_Receive_Onebyte, 1);//开启下一次接收中断
		}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值