news 2026/5/14 17:27:14

STM32 HAL 函数大全 · 第 2 卷

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
STM32 HAL 函数大全 · 第 2 卷

UART / USART 模块(通用同步/异步收发器)

版本:v1.0|适用系列:STM32F0 / F1 / F3 / F4 / F7 / L0 / L4 / H7


目录

  1. UART 模块简介

  2. 通信协议与参数配置

  3. 三大工作模式详解

  4. HAL UART API 函数全集

  5. 中断与 DMA 回调机制

  6. printf 重定向实现

  7. 实战工程示例:DMA不定长接收

  8. 调试技巧与常见避坑


1. UART 模块简介

UART(Universal Asynchronous Receiver/Transmitter)是嵌入式系统中最通用的串行通信接口。STM32 的 USART 外设功能非常强大,不仅支持标准的异步串口通信,还支持同步模式、单线半双工、LIN 总线、甚至 SmartCard 协议。

核心功能

  • 全双工异步通信:RX 和 TX 独立工作,同时收发。

  • 硬件流控 (RTS/CTS):防止高速传输时数据缓冲区溢出。

  • DMA 支持:实现零 CPU 占用的高速数据搬运。

  • 多处理器通信:支持静默模式和地址唤醒。

  • 同步同步模式 (USART)**:提供时钟输出 (SCLK),可驱动 SPI 从机设备。


2. 通信协议与参数配置

UART_InitTypeDef结构体或 CubeMX 中,核心配置参数如下:

参数名称HAL 宏定义示例说明
波特率BaudRate = 11520BaudRate = 115200`通信速度,双方必须严格一致。常用 9600, 115200。
数据位WordLength = UART_WORDLENGTH_8B数据帧长度,通常为 8 位。若开启奇偶校验,某些系列需设为 9 位。
停止位StopBits = UART_STOPBITS_1帧结束标志,通常为 1 位。
校验位Parity = UART_PARITYParity = UART_PARITY_NONE`奇偶校验,通常无校验 (None)。
流控HwFlowCtl = UART_HWCONTROL_NONE硬件流控,高速传输时建议开启 RTS/CTS。
模式Mode = UART_MODE_TX_RX开启发送 (TX) 和接收 (RX)。

注意:通信双方(例如 STM32 与 电脑串口助手)的所有参数必须完全一致,否则会出现乱码。


3. 三大工作模式详解

STM32 UART 数据收发主要有三种方式,适用于不同场景:

3.1 轮询模式 (Blocking / Polling)

  • 原理:CPU 在while循环中不断查询状态寄存器,直到发送/接收完成。

  • 优点:逻辑简单,无中断竞争。

  • 缺点严重阻塞 CPU,无法处理并发任务,容易丢数据。

  • 场景:系统初始化打印、简单的调试信息输出。

3.2 中断模式 (Non-Blocking / IT)

  • 原理:每接收或发送一个字节触发一次中断,CPU 暂停主程序去处理数据。

  • 优点:CPU 不需要死等,实时性好。

  • 缺点:大数据量时中断频繁,占用大量 CPU 资源(频繁压栈出栈)。

  • 场景:低速、低频的命令交互(如 AT 指令)。

3.3 DMA 模式 (Direct Memory Access)

  • 原理:DMA 控制器直接在内存(SRAM)和串口寄存器(DR)之间搬运数据,完成后才通知 CPU。

  • 优点CPU 零负载,适合高速、大数据流传输。

  • 缺点:配置相对复杂,处理不定长数据需配合空闲中断 (Idle Line)。

  • 场景:GPS 数据流、Modbus 协议、固件升级、高速传感器。


4. HAL UART API 函数全集

以下函数定义在stm32xx_hal_uart.c中:

4.1 初始化与控制

// 初始化 UART(底层调用 HAL_UART_MspInit 配置引脚和时钟) HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart); ​ // 反初始化(释放 IO 和时钟) HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart);

4.2 数据发送 (Transmit)

// 轮询发送 (阻塞,直到发送完 Size 字节或超时) HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout); ​ // 中断发送 (非阻塞) HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); ​ // DMA 发送 (非阻塞,推荐) HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);

4.3 数据接收 (Receive)

// 轮询接收 (阻塞) HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout); ​ // 中断接收 (非阻塞) HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); ​ // DMA 接收 (非阻塞) HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); ​ // DMA 接收 + 空闲中断检测 (处理不定长数据神器,部分新版 HAL 库支持) HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);

4.4 中断与状态

// 获取当前状态 HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart); ​ // 获取错误码 (如 ORE 溢出错误) uint32_t HAL_UART_GetError(UART_HandleTypeDef *huart);

5. 中断与 DMA 回调机制

HAL 库通过统一的中断处理函数分发事件,用户只需重写对应的__weak回调函数。

核心回调函数

回调函数名触发时机典型用途
HAL_UART_TxCpltCallback发送完成 (IT/DMA)切换 RS485 收发方向、启动下一次发送
HAL_UART_RxCpltCallback接收定长数据完成处理数据包、解析命令
HAL_UARTEx_RxEventCallbackHAL_UARTEx_RxEventCallback`接收完成或空闲中断触发DMA 不定长接收的核心处理处
HAL_UART_ErrorCallback发生错误 (如溢出 ORE)清除错误标志、重启接收

6. printf 重定向实现

为了让printf输出到串口,需重写标准库底层输出函数。

6.1 Keil (MDK) 环境

main.cusart.c中添加(需勾选 "Use MicroLIB"):

#include <stdio.h> ​ /* 重写 fputc */ int fputc(int ch, FILE *f) { HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF); return ch; }

6.2 GCC / STM32CubeIDE 环境

/* 重写 _write */ int _write(int file, char *ptr, int len) { HAL_UART_Transmit(&huart1, (uint8_t *)ptr, len, 0xFFFF); return len; }

7. 实战工程示例:DMA不定长接收

这是实际项目中处理 GPS、WIFI 模块数据最稳定、最高效的方案。

7.1 初始化 (main.c)

#define RX_BUF_SIZE 256 uint8_t RxBuf[RX_BUF_SIZE]; // 接收缓冲区 ​ int main(void) { HAL_Init(); SystemClock_Config(); MX_USART1_UART_Init(); MX_DMA_Init(); // 必须初始化 DMA ​ // 启动 DMA 接收并开启空闲中断 (IDLE IE) // 此时串口会将数据搬运到 RxBuf,直到缓冲区满或线路空闲 HAL_UARTEx_ReceiveToIdle_DMA(&huart1, RxBuf, RX_BUF_SIZE); ​ while (1) { // 主循环处理业务 } }

7.2 回调处理 (main.c)

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) { if (huart->Instance == USART1) { // Size 是实际接收到的字节数 // 1. 处理数据 (建议拷贝到其他 buffer 或置标志位,不要在此耗时) Process_Data(RxBuf, Size); ​ // 2. 必须重新开启接收 (DMA Normal 模式下) // 这里的 Size 参数是缓冲区最大长度 HAL_UARTEx_ReceiveToIdle_DMA(&huart1, RxBuf, RX_BUF_SIZE); } }

8. 调试技巧与常见避坑

  1. 乱码问题

    • 检查外部晶振频率 (HSE) 设置是否与板子实际一致(如 8M vs 25M)。

    • 检查波特率两端是否一致。

    • 检查共地 (GND)

  2. 接收中断只进一次

    • 轮询/中断模式下,ORE (Overrun Error)溢出错误会导致中断锁死。

    • 解决:在HAL_UART_ErrorCallback中清除错误标志,或在主循环检查并清除 ORE。

    • 中断回调中忘记再次调用HAL_UART_Receive_IT

  3. DMA 接收数据不更新**:

    • 在 Cortex-M7 (F7/H7) 上,若开启了 D-Cache,DMA 更新了 SRAM 但 CPU 读的是 Cache 旧值。

    • 解决:配置 MPU 将 DMA 缓冲区设为 Non-Cacheable,或调用SCB_InvalidateDCache_by_Addr

  4. printf 卡死: *

    • 未勾选 MicroLIB (Keil)。

    • 硬件上未连接 TX 线,导致一直等待发送完成

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/12 12:57:01

如何彻底清理显卡驱动:Display Driver Uninstaller完整使用指南

如何彻底清理显卡驱动&#xff1a;Display Driver Uninstaller完整使用指南 【免费下载链接】display-drivers-uninstaller Display Driver Uninstaller (DDU) a driver removal utility / cleaner utility 项目地址: https://gitcode.com/gh_mirrors/di/display-drivers-uni…

作者头像 李华
网站建设 2026/5/6 14:38:47

付费墙绕过工具终极指南:3分钟解锁付费新闻的完整方案

付费墙绕过工具终极指南&#xff1a;3分钟解锁付费新闻的完整方案 【免费下载链接】bypass-paywalls-chrome-clean 项目地址: https://gitcode.com/GitHub_Trending/by/bypass-paywalls-chrome-clean 你是否曾为了一篇深度报道而苦恼于付费墙的限制&#xff1f;当优质内…

作者头像 李华
网站建设 2026/5/13 4:11:03

从平面到空间:二维CAD与三维CAD的设计思维革命

在工程设计的发展长河中&#xff0c;计算机辅助设计&#xff08;CAD&#xff09;技术的演进不仅是一场工具革命&#xff0c;更是一次深刻的设计思维转型。从二维CAD到三维CAD的跨越&#xff0c;标志着工程设计从“纸上谈兵”进入了“虚拟现实”的新纪元。二维CAD&#xff1a;平…

作者头像 李华
网站建设 2026/5/14 7:00:09

三维CAD:现代设计的核心引擎

三维计算机辅助设计&#xff08;3D CAD&#xff09;已彻底革新了工程设计领域&#xff0c;它不再仅仅是二维图板的电子替代&#xff0c;而是一个集成建模、分析、制造和数据管理的综合平台。其核心价值在于构建精确的数字化模型&#xff0c;并以此为核心贯穿产品从概念到成品的…

作者头像 李华
网站建设 2026/5/5 6:58:25

KeyShot许可证多用户共享设置

在3D渲染领域&#xff0c;团队协作往往涉及到多个用户同时使用同一份许可证。为了满足这一需求&#xff0c;KeyShot提供了多用户共享设置功能&#xff0c;使得许可证能够在团队成员之间高效共享&#xff0c;提升协作效率。本文将为您详细介绍KeyShot许可证多用户共享设置的优势…

作者头像 李华
网站建设 2026/5/10 11:06:11

5个步骤解锁全球付费内容:Bypass Paywalls Clean深度体验

你是否曾在深夜急需查阅知名媒体的深度分析&#xff0c;却被付费墙无情阻挡&#xff1f;当权威商业媒体的商业洞察就在眼前&#xff0c;却因订阅费用望而却步&#xff1f;今天&#xff0c;我将分享一款改变阅读体验的实用工具——Bypass Paywalls Clean&#xff0c;它如何让付费…

作者头像 李华