单片机帧头帧尾数据不定长接收-STM32

串口数据带帧头帧尾数据接收整体思路:

    1.串口中断函数接收到数据后判断每一个字节的值;

    2.如果串口数据是帧头数据,则帧头帧尾计次++;

    3.帧头帧尾计次值判断,如果帧头值、计次值正确,则将数据转移;

    4.帧尾判断,如果正确,接收成功标志位置1;

    5.接收成功标志位置1后,数据解析;

    6.解析完成后,标志位清0。

keil5配置

  .h文件

#ifndef __MY_UART_H_
#define __MY_UART_H_
 
 
#include  "stdint.h"
#include  "usart.h"
#include  "string.h"
 
 
#define BUF_SIZE  64
 
 
#define  Head1   0xAA
#define  Head2	 0xBB
#define  Head3 	 0xCC
#define  End1    0xDD
#define  End2  	 0xEE
#define  End3    0xFF
 
 
typedef struct{
	
	
   uint8_t Rx_data;//数据接收
	
   uint8_t Rx_buf[BUF_SIZE];//字节转移缓存区
	
   uint8_t Rx_flag;//接收到数据标志位
   uint8_t Rx_succeed;//接收到正确的帧头、帧尾数据
   uint8_t Rx_Index;//接收索引
   uint8_t Rx_count;//帧头帧尾计次判断
 
   uint16_t Data_CRC;//数据校验
	 
	 uint8_t data_error;//数据解析错误
	
} Rx_flag;
 
 
void Data_dispose(void);
 
 


#endif

  .c文件

#include "my_uart.h"
 
 
Rx_flag Rx_State = {0};
 
 


/*
CRC表

*/




/********************
  函数名:串口初始化
  
********************/
void UART_Init(void)
{
   
  HAL_UART_Receive_IT(&huart2,&Rx_State.Rx_data,sizeof(Rx_State.Rx_data));  
 
}
 

/********
函数名:串口中断回调函数
UART_HandleTypeDef *huart:传入的串口句柄指针
********/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
 
 
		if(huart == &huart2)
		{
		
          HAL_UART_Receive_IT(&huart2,&Rx_State.Rx_data,sizeof(Rx_State.Rx_data)); 
 
			switch(Rx_State.Rx_flag)//数据判断
			{
			  case 0:
		         if(Rx_State.Rx_data == Head1)
				 {	 
					 Rx_State.Rx_count++;//帧头计次						 
					 Rx_State.Rx_flag = 0;
					 
				 }
					 
				 if(Rx_State.Rx_data == Head2 && Rx_State.Rx_count == 1)
				 { 
					Rx_State.Rx_count++;//帧头帧尾计次						 
					Rx_State.Rx_flag = 0;
				 }
					
				 if(Rx_State.Rx_data == Head3 && Rx_State.Rx_count == 2)
				 {					 
					Rx_State.Rx_count++;//帧头帧尾计次						 
					Rx_State.Rx_flag = 1;//帧头判断完成,准备将字节转移至缓存区
				 }
				
                 break;
			  case 1:
			    //数据传入接收缓存区内	
				Rx_State.Rx_buf[Rx_State.Rx_Index++] = Rx_State.Rx_data;
						      
				if(Rx_State.Rx_data  == End1 && Rx_State.Rx_count == 3)
			    {					 
				   Rx_State.Rx_count++;//帧头帧尾计次						 
				   Rx_State.Rx_flag = 1;			 
				}
					 
				if(Rx_State.Rx_data  == End2 && Rx_State.Rx_count == 4)
				{				 
				   Rx_State.Rx_count++;//帧头帧尾计次						 
				   Rx_State.Rx_flag = 2;			 
				 }
					 
				break;			
			  case 2:
                        //在此可增加CRC校验
 
				if(Rx_State.Rx_data  == End3 && Rx_State.Rx_count == 5)
				{						 
				   Rx_State.Rx_count++;//帧头帧尾计次						 
				   Rx_State.Rx_flag = 3;				 
				   Rx_State.Rx_succeed = 1;//数据接收成功标志位						 
				}
					 
				break;
			  default:	
                   Rx_State.Rx_flag = 0;				
			    break;
		
			}
				
		}
 
}
 
 
 
/****************
数据解析函数
****************/
 
void Data_dispose(void)
{
			
	if(Rx_State.Rx_succeed == 1)//数据接收成功标志位
	{
		
		 Rx_State.Data_CRC = VerifyCRC16(&Rx_State.Rx_buf[0],Rx_State.Rx_Index - 3);//数据校验
	   
 
		//数据解析
		 if(Rx_State.Data_CRC == (Rx_State.Rx_buf[Rx_State.Rx_Index - 3] >> 8) + Rx_State.Rx_buf[Rx_State.Rx_Index - 4])
		 {
		 
		 
		 
		 }
		 else
		 {
			
		  Rx_State.data_error = 1;//数据解析错误标志位
		
		 }
		 
		
	   /*数据标志位、索引、计次、缓存区清0,为下一次数据的到来做准备*/
	 	
		 memset(&Rx_State,0,sizeof(Rx_State));//缓存区清0
		
		
	}
			
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值