stm32串口接收程序 分帧处理

拈花ヽ惹草 提交于 2019-11-30 06:22:54

stm32串口接收程序 分帧处理


  接收程序是所有单片机入门教程的必经之路,但是很多教程和例程只讲了如何去接收一个8位的字符数据,但实际操作时我们常常需要接收的是各式各样的数据帧,这一章主要介绍如何去进行分帧操作。

采用状态机的分帧方式

  采用状态机的方式可以完成目前绝大多数的串口数据的分帧操作。
  目前比较常用的数据帧格式由帧头,数据帧种类,数据帧长度,数据帧内容,帧尾,校验码等部分组成,像一些毫米波雷达、激光雷达等模块的数据帧都采用这种方式我们以一款简单的miniMPU模块为例进行分帧处理。
   miniMPU的返回的数据帧有两种一种是接收的原始数据、如三轴加速度、大气压等,另一种是经过处理后的计算数据如俯仰角等。数据帧示例如下A55A12A1……78B4。
   其中A55A为数据帧的帧头;12为数据帧的长度即0X12=18;A1代表接收的是第一种数据。……代表采集到的数据,按说明书解析即可,78为数据的校验码,计算方式为将……部分采集到的所有数值相加最后的8位字符即为校验码,B4为帧尾。
   分帧操作的代码如下

void USART1_IRQHandler(void)                	//串口1中断服务程序
{
	static u8 states = 0;//状态机状态码
	static u8 i=0;//二维数组的第一个参数
	static u8 j=0;//二维数组的第二个参数
	static u8 check=0;//校验码
	static strlen=0;//本次接收数据帧的长度
	u8 res;
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断
	{
		res =USART_ReceiveData(USART1);//(USART1->DR);	//读取接收到的8位字符
		switch(states)
		{
			case 0://case 0,1判断是否收到帧头,如果是,接收数据长度,否,继续等待帧头。
				if(res == 0xA5)
				{
					i=0;
					j=1;
					USART1_RX_BUF[0][0]=0;//第一位为标志位,为0代表改数据为有误数据或未接收完成,为一代表可用
					USART1_RX_BUF[1][0]=0;
					check=0;
					states = 1;
				}
				break;	
			case 1:
				if(res == 0x5A)
				{
					states = 2;
				}
				else
					states = 0;
				break;	
			case 2://接收数据长度,如果长度异常,放弃这帧数据返回状态1等待下一帧数据
				states = 3;
				if(res>10&&res<50)
				{
					strlen=res;
				}
				else 
					states = 0;
				break;
			case 3://判断接收数据帧种类,如果异常放弃这帧数据
				states = 4;
				if(res==0xA1)
				{
					i = 0;
				}
				else if(res==0xA2)
				{
					i = 1;
				}
				else
					states = 0;
				break;
			case 4://接收其余的数据并判断数据是否正常
				USART1_RX_BUF[i][j]=res;
				j++;
				if(j>strlen-2)//由于并没有接收数据长度位和数据种类位所以需要-2,具体长度根据接收的数据帧格式和代码进行修改,不可照抄。
					{
						for(j=0;j<strlen-4;j++)
						{
							check=check+USART1_RX_BUF[i][j];//按照数据帧说明计算校验码,不可照抄
						}
						if(USART1_RX_BUF[i][strlen-4]==check)//验证校验码是否正确
						{
							if(USART1_RX_BUF[i][strlen-3]==0xB4)//验证数据帧结尾是否正确
							{
								USART1_RX_BUF[i][0]=1;//接收完成,数据帧正常
							}
						}
						states = 0;//返回状态0等待下一帧数据
					}
				}
				break;	
		}
	} 
	USART_ClearFlag(USART1,USART_FLAG_TC);
} 	

   接收结束的二维数组USART1_RX_BUF中数组USART1_RX_BUF[0]接收的第一种数据,USART1_RX_BUF[1]接收的第二种数据,每个数组的第一位为接收状态(0为错误,1为接收完成)其余位位接受到的具体数值。
   代码请思考修改后在使用,勿直接照抄。代码逻辑上可能还存在一些bug希望各位大佬多多指教。
  觉得还不错的化记得点赞啊

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!