STM32实现串口接收不定长数据

原理

STM32实现串口接收不定长数据,主要靠的就是串口空闲(idle)中断,此中断的触发条件与接收的字节数无关,只有当Rx引脚无后续数据进入时(串口空闲时),认为这时候代表一个数据包接收完成了,在此时中断,对数据进行分析处理即可。

实现

具体实现方式就是使用HAL库的扩展函数(写在main函数里)

cpp 复制代码
HAL_UARTEx_ReceiveToIdle_DMA(&huart2,DATE,50);

Ex 代表扩展,idle代表空闲中断,

参数:指针地址,变量,(一次性能接受的最大长度,一般是数组长度)


接下来重写回调函数

cpp 复制代码
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)

这个RXEvevtCallback与之前的RXCpltCallback,一个重要区别就是多了一个入参Size

因为之前都是已知数据长度,但RXEvevtCallback用于接收不定长数据,所以用Size来确认到底有几个数据,来发送 与接收数据相同的 字节数。

来看整体代码

cpp 复制代码
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
	if(huart == &huart2)
	{
		HAL_UART_Transmit_DMA(&huart2,DATE,Size);
		HAL_UARTEx_ReceiveToIdle_DMA(&huart2,DATE,50);
	}
}

注意(1)

这里要养成好习惯: 确定 是通道二 之后再执行操作。

注意(2)

使用DMA时,会出现 "过半传输中断" 的情况,即数据传输一半便会 调用回调函数。

所以要 把他关闭。

用这段代码关闭。

cpp 复制代码
__HAL_DMA_DISABLE_IT(&hdma_usart2_rx,DMA_IT_HT);

参数:指针地址,要关闭的中断

所以刚才的代码应该是

cpp 复制代码
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
	if(huart == &huart2)
	{
		HAL_UART_Transmit_DMA(&huart2,DATE,Size);
		HAL_UARTEx_ReceiveToIdle_DMA(&huart2,DATE,50);
		
		__HAL_DMA_DISABLE_IT(&hdma_usart2_rx,DMA_IT_HT);
	}
}

别忘了程序开始时也要关闭噢。

cpp 复制代码
 MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
  
  HAL_UARTEx_ReceiveToIdle_DMA(&huart2,DATE,50);
  __HAL_DMA_DISABLE_IT(&hdma_usart2_rx,DMA_IT_HT);
相关推荐
范纹杉想快点毕业2 小时前
ZYNQ PS 端 UART 接收数据数据帧(初学者友好版)嵌入式编程 C语言 c++ 软件开发
c语言·笔记·stm32·单片机·嵌入式硬件·mcu·51单片机
方圆工作室2 小时前
51单片机驱动数码管
单片机·嵌入式硬件·51单片机
乔宕一3 小时前
stm32 链接脚本没有 .gcc_except_table 段也能支持 C++ 异常
c++·stm32·嵌入式硬件
范纹杉想快点毕业4 小时前
STM32 串口接收数据包(自定义帧头帧尾)
stm32·单片机·嵌入式硬件
茯苓gao5 小时前
STM32G4 电流环闭环
笔记·stm32·单片机·嵌入式硬件·学习
单片机系统设计6 小时前
基于stm32的环境监测系统/智能家居/空气质量监测系统
stm32·单片机·嵌入式硬件·毕业设计·智能家居
不知所云,6 小时前
5. STM32 时钟系统分配
stm32·单片机·嵌入式硬件
电子科技圈8 小时前
芯科科技FG23L无线SoC现已全面供货,为Sub-GHz物联网应用提供最佳性价比
科技·嵌入式硬件·mcu·物联网·制造·智能硬件·交通物流
天天爱吃肉82189 小时前
【比亚迪璇玑架构深度解析:重新定义智能电动汽车的“整车智能”】
数据库·人工智能·嵌入式硬件·架构·汽车
糖糖单片机设计9 小时前
硬件开发_基于物联网的沼气池环境监测系统
stm32·单片机·嵌入式硬件·物联网·51单片机