HAL库的串口

普通串口:

直接打开一个串口的异步功能

发送函数:

cs 复制代码
 HAL_UART_Transmit(&huart5,buf,sizeof(buf),50);
//HAL_UART_Transmit(句柄,发送的内容,内容长度,允许的发送时间ms);

接收函数:(堵塞接收,在设定时间内都会访问串口数据)

cs 复制代码
HAL_UART_Receive(&huart5,buf,sizeof(buf),HAL_MAX_DELAY);
//HAL_UART_Receive(句柄,接收数组,接受数据长度,允许等待的时间);
//HAL_MAX_DELAY  == 死等待发送

中断串口:

普通串口+打开全局中断

发送数据:

cs 复制代码
HAL_UART_Transmit_IT(&huart5,buf,sizeof(buf));
//HAL_UART_Transmit_IT(句柄,发送的数据,数据长度);
/*
用中断,所以较普通串口少了一个允许发送的时间
HAL_UART_Transmit(&huart5,buf,sizeof(buf),50);
*/

接收数据:(非堵塞接收,靠串口中断读取数据)

cs 复制代码
HAL_UART_Receive_IT(&huart5,buf,sizeof(buf));
//HAL_UART_Receive_IT(句柄,数据缓存,数据长度);
/*
用中断,所以较普通串口少了一个允许等待的时间
HAL_UART_Receive(&huart5,buf,sizeof(buf),HAL_MAX_DELAY);
*/

较普通串口新增功能:串口中断

(但是这个中断汇总了很多中断类型:发送完成中断、接收完成中断;所以需要使用HAL_UART_IRQHandler其内部的函数,而非直接这个外框)

串口读取完成回调函数,当串口接收到目标数据长度后,会执行这个函数。

需要在自己需要的串口数据处理函数中,重新编写这个函数的功能,来实现接受数据后的数据处理。

cs 复制代码
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	HAL_UART_Transmit_IT(&huart5,buf,2);//返回接收的数据

		/*
		自己编写的串口数据处理代码
		如:
			if(buf[0] == 0xff)	//帧头
			{
				if(buf[5] == 0xfa)	//帧尾
			}
		
		*/
		
		//重新打开串口接收
	HAL_UART_Receive_IT(&huart5,buf,2);

}

使用举例:

但是这个中断需要接收到目标字符串长度才算完成一次接收,未达到则等待后续数据

DMA+串口空闲中断(ToIdle)发生时就是发送数据完成。

在中断的基础上添加TX和RX的DMA

使用的接收函数:

cpp 复制代码
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
/*
句柄、数据接收数组、单次最大数据长度

*/

对应的回调函数:句柄、接收到的数据长度

cs 复制代码
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
	if(huart == &MyHuart)//判断是哪个串口进入的回调函数
	{
		HAL_UART_Transmit_DMA(&huart5,buf,Size);//Sizes是收到的数据长度
		/*
		自己编写的串口数据处理代码
		如:
			if(buf[0] == 0xff)	//帧头
			{
				if(buf[5] == 0xfa)	//帧尾
			}
		
		*/
		
		//重新打开串口接收
		HAL_UARTEx_ReceiveToIdle_DMA(&huart5,buf,sizeof(buf));
	}
}

中断串口和DMA串口的区别:

特性 普通轮询(Polling) 中断(IT) DMA
原理 CPU 不断查询标志位 数据到达后触发中断 硬件自动搬运数据,不占用 CPU
CPU 占用 高(阻塞式等待) 中(中断响应时间) 低(仅初始化时占用)
实时性 差(阻塞其他任务) 高(及时响应) 高(后台自动传输)
适用场景 简单调试、单任务环境 中低速数据(如指令解析) 高速数据(如摄像头、音频)
函数示例 HAL_UART_Transmit HAL_UART_Transmit_IT HAL_UART_Transmit_DMA
接收函数示例 HAL_UART_Receive HAL_UART_Receive_IT HAL_UART_Receive_DMA
是否需要回调函数 否 是(如 HAL_UART_RxCpltCallback) 是(如 HAL_UART_RxCpltCallback)
空闲中断支持 不支持 不支持 支持(HAL_UARTEx_ReceiveToIdle_DMA)
硬件依赖 无 需启用 UART 中断 需配置 DMA 通道

总结:

特性 普通轮询(Polling) 中断(IT) DMA
工作原理 CPU 阻塞等待数据收发完成 数据收发完成后触发中断回调 硬件自动搬运数据,空闲中断触发回调
函数示例(发送) HAL_UART_Transmit(&huart, data, len, timeout) HAL_UART_Transmit_IT(&huart, data, len) HAL_UART_Transmit_DMA(&huart, data, len)
函数示例(接收) HAL_UART_Receive(&huart, data, len, timeout) HAL_UART_Receive_IT(&huart, data, len) HAL_UART_Receive_DMA(&huart, data, len) 或 HAL_UARTEx_ReceiveToIdle_DMA(推荐)
CPU 占用 高(完全阻塞) 中(中断响应时间) 极低(仅初始化时占用)
实时性 差 高 最高(后台自动传输)
重启接收 不需要 需要 (在回调中手动调用 HAL_UART_Receive_IT) 需要 (在回调中调用 HAL_UARTEx_ReceiveToIdle_DMA)
中断配置 无 需开启 UART 全局中断(NVIC) 需开启 UART 空闲中断 + DMA 中断
关闭半传输中断 无 无 需要 (调用 __HAL_DMA_DISABLE_IT(&hdma, DMA_IT_HT))
适用场景 单任务调试、简单指令 中低速数据(如协议解析) 高速数据(如传感器流、图像传输)
相关推荐
szxinmai主板定制专家12 小时前
X86 工控机 vs RK3588 异构主控:AMR 控制器 BOM、散热、长期运维对比
运维·stm32·单片机·嵌入式硬件·fpga开发·am62x
HQB202614 小时前
屹晶微电子 EG1130|2‑24V 输入 / 最高 28V 输出 内置 MOS 异步升压 DC‑DC|SOT23‑6|摄像头 / 车充 / 电池充电电源
嵌入式硬件·硬件工程
泛凡(Linyongui)16 小时前
基于 CW32L010 的智能厨卫调温旋钮方案--低成本 EC21 编码旋钮全解析
单片机·嵌入式硬件·c#
十年磨一剑~16 小时前
Linux 内核中断处理机制与软硬件协同流程
linux·嵌入式硬件
糖糖单片机设计17 小时前
基于单片机的热水器节能控制系统
单片机·嵌入式硬件
数字新视界18 小时前
数字孪生技术赋能智能化转型与创新实践
嵌入式硬件·物联网·系统架构·机房管理·动力与环境监控系统
HQB202618 小时前
屹晶微电子 EG1195|10‑120V/10A+ 外置 MOS 异步降压控制器|ESOP‑8|电动车转换器 / 快充 / 工业电源
嵌入式硬件·硬件工程
不悔哥19 小时前
开源LineageOS:旧手机刷上开源系统
嵌入式硬件·智能手机·开源
服务器硬件项目经理20 小时前
《超节点修仙录》· 第一卷·炼气期【第04话】 超节点 vs 普通服务器——不就是多插了几张卡吗?
运维·服务器·人工智能·嵌入式硬件·深度学习·机器学习
一次调频AGCAVC20 小时前
一次调频系统控制柜的组成及一次调频装置主机功能详述
人工智能·嵌入式硬件