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

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

按下面步骤修改实测可用
步骤:
在这里插入图片描述
添加串口接收所需变量
  打开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 */
}
  • 10
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32 HAL库中,串口接收不定数据的方式可以通过使用中断实现。以下是一些基本步骤: 1. 配置串口工作模式为中断模式 ``` UART_HandleTypeDef huart; huart.Instance = USARTx; huart.Init.BaudRate = 115200; huart.Init.WordLength = UART_WORDLENGTH_8B; huart.Init.StopBits = UART_STOPBITS_1; huart.Init.Parity = UART_PARITY_NONE; huart.Init.Mode = UART_MODE_TX_RX; huart.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart.Init.OverSampling = UART_OVERSAMPLING_16; huart.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; huart.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; HAL_UART_Init(&huart); /* Enable UART RX interrupt */ __HAL_UART_ENABLE_IT(&huart, UART_IT_RXNE); ``` 2. 实现串口接收中断服务函数 ``` void USARTx_IRQHandler(void) { uint32_t isrflags = READ_REG(huart.Instance->SR); if (isrflags & USART_SR_RXNE) { /* Read data from the USART RX register */ uint8_t rx_data = (uint8_t)(huart.Instance->DR & 0xFF); /* Process the received data */ // ... } } ``` 3. 在中断服务函数中处理接收的数据 在中断服务函数中,读取接收数据寄存器中的数据,并进行处理。处理方式可以根据具体应用场景而定。例如,可以将接收的数据存储到一个缓冲区中,直到达到特定条件时再进行处理。 注意事项: - 在中断服务函数中,要根据实际情况判断接收到的数据是否已经达到预期长度,防止缓冲区溢出等问题。 - 在处理接收数据时,要注意保护共享资源的安全,例如使用互斥锁等机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值