hal库stm32串口接收不定长数据

参考博客:
https://blog.csdn.net/qq_41830158/article/details/121254705

按下面步骤修改实测可用
步骤:
hal库stm32串口接收不定长数据_第1张图片
添加串口接收所需变量
  打开uart.c文件,在文件顶部的USER CODE BEGIN 0下方添加下列变量

volatile uint8_t rx1_len = 0;  //接收一帧数据的长度
volatile uint8_t rec1_end_flag = 0; //一帧数据接收完成标志
uint8_t rx1_buffer[BUFFER_SIZE]={0};  //接收数据缓存数组

添加串口及IDLE处理函数
  打开uart.c文件,在文件末尾的USER CODE BEGIN 1下方添加下列函数

void Usart1_IDLE(void)      //USART1的IDLE接收
{   
	uint32_t tmp_flag = 0;   
	uint32_t temp;
   	tmp_flag =__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE); //获取IDLE标志位
   if((tmp_flag != RESET))//idle标志被置位
   {
   		__HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除标志位
   		HAL_UART_DMAStop(&huart1); //  停止DMA传输,防止
   		temp  =  __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);// 获取DMA中未传输的数据个数   
   		rx1_len =  BUFFER_SIZE - temp; //总计数减去未传输的数据个数,得到已经接收的数据个数
   		rec1_end_flag = 1;	// 接受完成标志位置1	
   }
}

void Usart1_Handle()     //USART1对接收的一帧数据进行处理
{
   DMA_Usart1_Send(rx1_buffer, rx1_len);  //将接收到的数据回发给发送端
   rx1_len = 0;//清除计数
   rec1_end_flag = 0;//清除接收结束标志位
   HAL_UART_Receive_DMA(&huart1,rx1_buffer,BUFFER_SIZE);//重新打开DMA接收
}

void DMA_Usart1_Send(uint8_t *buf,uint8_t len) //串口发送封装
{   
	if(HAL_UART_Transmit_DMA(&huart1,buf,len)!= HAL_OK) //判断是否发送正常,如果出现异常则进入异常中断函数
	{
  		Error_Handler();
 	}
}

声明变量及函数
  打开usart.h文件,在文件开头的USER CODE BEGIN Includes下方添加如下语句

#include "stdio.h"
#include "string.h"
#define BUFFER_SIZE  100  

extern volatile uint8_t rx1_len;  //接收一帧数据的长度
extern volatile uint8_t rec1_end_flag; //一帧数据接收完成标志
extern uint8_t rx1_buffer[BUFFER_SIZE];  //接收数据缓存数组

void Usart1_Handle(void);
void DMA_Usart1_Send(uint8_t *buf,uint8_t len);//串口发送封装
void Usart1_IDLE(void);

启用IDLE中断
  进入main.c文件,找到入口函数void mian(void), 在USER CODE BEGIN 2下方开启串口1的DILE中断,并打开DMA接收。

	__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //使能IDLE中断	
  	HAL_UART_Receive_DMA(&huart1,rx1_buffer,BUFFER_SIZE);  //开启DMA接收

在while语句中添加接收查询语句。

if(rec1_end_flag)  //判断是否接收到1帧数据
{
	Usart1_Handle();  //前往数据处理函数处理接收到的数据。
}		

修改中断文件stm32f1xx_it.c,在中断处理函数中添加Usart1_IDLE();

void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
  Usart1_IDLE();
  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */

  /* USER CODE END USART1_IRQn 1 */
}

你可能感兴趣的:(stm32f103,stm32,单片机,串口接收不定长数据)