Bootstrap

STM32的一种串口数据接受方式

项目要求控制12路电磁阀,电磁阀的控制帧格式尾 头帧0xFB ,数据位xxx,尾帧0xFB。在串口中断回调函数中做出如下的实现。

uint8_t start_Flag=0;//数据开始标志位

uint8_t cont=0;//数据计数位

uint8_t RX_Buff[16];//数据缓存

uint8_t flash_Fiag=0;//数据接受完成

//串口中断回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance==USART1)
	{
		if(temp==0xFB)//开始帧
		{
			start_Flag=1;
			RX_Buff[cont++]=temp;
		}
		else if(temp==0xBF)//结束帧
		{
			start_Flag=0;
			RX_Buff[cont]=temp;
			flash_Fiag=1;
			cont=0;
		}
		else//过程帧
		{
				if(start_Flag==1)
				{
					RX_Buff[cont++]=temp;
					if(cont>=16)//数据溢出检测
					{
						start_Flag=0;
					}
				}
		}
	}
	HAL_UART_Receive_IT(huart,&temp,1);//每次接收结束都需要开启接收中断
}

清除接受缓冲区数据

void clean_RX_Data(void)
{
	for(int i=0;i<16;i++)
	{
		 RX_Buff[i]=0;
	}
}

主循环while(1)中添加如下函数,之后改进以后可以使用定时器专门负责接收数据,每50ms接收一次数据。

		if(flash_Fiag==1)//可以用定时器检测数据接受 如果数据接受完了
		{
			flash_Fiag=0;
			for(int i=0;i<16;i++)
			{
				final_Data[i]=RX_Buff[i];
			}
			clean_RX_Data();
		}

实验现象:阿波罗F429测试,发送报头报尾,返回数据和发送数据一致。
在这里插入图片描述
项目拓展:在此基础上,可以直接通过final_Data[i]中的数组元素做出相应的控制判断!!!

2022.4.22 改良

数据结构的封装:

typedef struct __MY_USART
{
	uint8_t RX_start_Flag;//接收开始
	uint8_t RX_end_Flag;//接收结束
	uint8_t RX_finsh_Flag;//接收完成
	uint8_t RX_Data[8];//
	
	uint8_t TX_start_Flag;
	uint8_t TX_end_Flag;
	uint8_t TX_finsh_Flag;
	uint8_t TX_Data[8];
	
	uint8_t cont;
	
}MY_USART;

改良的串口回调函数


void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance==USART1)
	{
		if(temp==0xFB)//开始帧
		{
			usart.RX_start_Flag=1;
			usart.cont=0;
			usart.RX_Data[usart.cont++]=temp;
		}
		else if(temp==0xBF)//结束帧
		{
			usart.RX_end_Flag=1;
			usart.RX_start_Flag=0;
			usart.RX_Data[usart.cont]=temp;
		}
		else//过程帧
		{
			if(usart.RX_start_Flag==1)
			{
				if(usart.cont<8)
				{
					usart.RX_Data[usart.cont++]=temp;
				}
				else
				{
					usart.RX_start_Flag=0;
				}
			}
		}
		
	}
	HAL_UART_Receive_IT(huart,&temp,1);
}

接收数据判断置于定时器中断,每50ms接收更新一次数据

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance==TIM6)
	{
	
		if(usart.RX_end_Flag==1)
		{
				usart.RX_end_Flag=0;
				memcpy(final_Data,usart.RX_Data,8);
				memset(usart.RX_Data,0,8);
				usart.RX_finsh_Flag=1;
		}
		HAL_TIM_Base_Start_IT(&htim6);
	}	
}

main函数while循环主函数设计:

	if(usart.RX_finsh_Flag==1)
		{
			usart.RX_finsh_Flag=0;
			for(int i=0;i<8;i++)
			{
				printf("%c",final_Data[i]);
			}
		}

结果显示:发送什么数据,返回什么数据。
在这里插入图片描述

;