目录
- [UART 简介](#UART 简介)
- [UART 工作原理](#UART 工作原理)
- [STM32 UART 硬件架构](#STM32 UART 硬件架构)
- [STM32 UART 软件配置(HAL 库)](#STM32 UART 软件配置(HAL 库))
- 常见应用场景
- 调试技巧与常见问题
- 参考资源
1. UART 简介
1.1 什么是 UART
UART (Universal Asynchronous Receiver/Transmitter,通用异步收发传输器)是一种串行、异步、全双工的通信协议,广泛应用于嵌入式系统中设备间的短距离数据传输。
1.2 UART vs USART
| 特性 | UART | USART |
|---|---|---|
| 全称 | Universal Asynchronous R/T | Universal Synchronous/Asynchronous R/T |
| 同步模式 | 不支持 | 支持(如 SPI 模式) |
| 异步模式 | 支持 | 支持 |
| 常见用途 | 调试打印、模块通信 | 需要时钟同步的场景 |
STM32 的串口外设通常称为 USART,但默认工作于异步模式时即等效为 UART。
1.3 核心特点
- 异步通信:无需共享时钟线,依靠双方约定的波特率同步
- 全双工:可同时发送(TX)和接收(RX)
- 点对点:典型连接为两根数据线(TX ↔ RX,RX ↔ TX)
- 电平标准:TTL(3.3V/5V)、RS-232、RS-485 等
2. UART 工作原理
2.1 数据帧格式
UART 数据传输以**帧(Frame)**为单位,典型格式如下:
| 起始位 | 数据位(5-9 bit)| 校验位(可选)| 停止位(1-2 bit)|
| 字段 | 说明 |
|---|---|
| 起始位 | 1 位低电平(0),标志帧开始 |
| 数据位 | 实际传输数据,通常为 8 位(1 Byte) |
| 校验位 | 可选(奇校验 / 偶校验 / 无校验) |
| 停止位 | 1 位或 2 位高电平(1),标志帧结束 |
2.2 波特率(Baud Rate)
波特率表示每秒传输的码元数,常见值:
9600(低速、稳定)115200(高速、常用调试波特率)921600(高速下载/传输)
双方波特率必须一致,否则会出现乱码。
2.3 通信流程
发送方:数据 → 并转串 → 按帧格式发送 → TX 引脚输出
接收方:RX 引脚采样 → 检测起始位 → 按波特率采样数据位 → 串转并
2.4 硬件连接
设备 A 设备 B
TX ──────────► RX
RX ◄────────── TX
GND ────────── GND (必须共地)
注意:TX 接 RX,RX 接 TX,GND 必须相连!
3. STM32 UART 硬件架构
3.1 主要寄存器
| 寄存器 | 功能 |
|---|---|
| USART_SR | 状态寄存器(TXE、RXNE、TC、ORE 等标志位) |
| USART_DR | 数据寄存器(读写数据) |
| USART_BRR | 波特率寄存器(设置分频系数) |
| USART_CR1/2/3 | 控制寄存器(使能、中断、模式配置) |
3.2 波特率计算
STM32 波特率公式:
BaudRate = fCK / (16 × USARTDIV)
其中:
fCK:USART 时钟频率(如 APB1/APB2 总线时钟)USARTDIV:写入 BRR 寄存器的分频值
HAL 库会自动计算,通常无需手动干预。
3.3 中断与 DMA
| 方式 | 特点 | 适用场景 |
|---|---|---|
| 轮询(Polling) | 简单、阻塞 CPU | 简单收发、初始化阶段 |
| 中断(Interrupt) | 非阻塞、响应快 | 中等数据量、实时性要求 |
| DMA | 不占用 CPU、大数据量 | 高速流、大量数据收发 |
4. STM32 UART 软件配置(HAL 库)
4.1 CubeMX 配置步骤
- 打开 STM32CubeMX,选择对应芯片型号
- 选择 USART 外设(如 USART1)
- 设置模式为 Asynchronous
- 配置参数:
- Baud Rate:
115200 - Word Length:
8 Bits - Stop Bits:
1 - Parity:
None
- Baud Rate:
- 开启 NVIC 中断(如使用中断方式)
- 生成代码
4.2 轮询方式收发
#include "stm32f1xx_hal.h"
UART_HandleTypeDef huart1;
// 初始化(CubeMX 自动生成)
void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
HAL_UART_Init(&huart1);
}
// 发送数据
uint8_t tx_buf[] = "Hello STM32 UART!\r\n";
HAL_UART_Transmit(&huart1, tx_buf, sizeof(tx_buf), 1000);
// 接收数据
uint8_t rx_buf[64];
HAL_UART_Receive(&huart1, rx_buf, 10, 1000); // 阻塞接收 10 字节
4.3 中断方式收发
// 启动中断接收
HAL_UART_Receive_IT(&huart1, rx_buf, 1); // 接收 1 字节触发中断
// 中断回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART1)
{
// 处理接收到的数据 rx_buf[0]
HAL_UART_Receive_IT(&huart1, rx_buf, 1); // 重新启动接收
}
}
4.4 DMA 方式收发
// 启动 DMA 发送
HAL_UART_Transmit_DMA(&huart1, tx_buf, len);
// 发送完成回调
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
// 发送完成处理
}
4.5 printf 重定向(调试必备)
#include <stdio.h>
// 重定向 printf 到 UART
int _write(int file, char *ptr, int len)
{
HAL_UART_Transmit(&huart1, (uint8_t*)ptr, len, HAL_MAX_DELAY);
return len;
}
// 使用
printf("Temperature: %.2f C\r\n", temp);
5. 常见应用场景
5.1 调试打印(Debug)
最常用的场景,通过 UART 输出日志到 PC 串口助手。
printf("[INFO] System initialized.\r\n");
printf("[ERROR] Sensor read failed!\r\n");
5.2 与蓝牙模块通信(如 HC-05/HC-06)
STM32 UART ──► HC-05 ──► 手机蓝牙
配置波特率通常为 9600,通过 AT 指令或透传模式通信。
5.3 GPS 模块数据解析(如 NEO-6M)
GPS 模块通过 UART 输出 NMEA 协议数据:
$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47
5.4 与 WiFi 模块通信(如 ESP8266/ESP32)
通过 AT 指令控制 WiFi 模块连接网络:
HAL_UART_Transmit(&huart2, (uint8_t*)"AT+CWMODE=1\r\n", 15, 1000);
HAL_UART_Transmit(&huart2, (uint8_t*)"AT+CWJAP="SSID","PWD"\r\n", 30, 10000);
5.5 RS-485 工业通信
通过 UART + RS-485 收发器实现远距离(>1000m)、多节点通信,常用于 Modbus RTU 协议。
6. 调试技巧与常见问题
6.1 常见问题排查
| 现象 | 可能原因 | 解决方法 |
|---|---|---|
| 输出乱码 | 波特率不匹配 | 检查双方波特率设置 |
| 无输出 | TX/RX 接反、未共地 | 检查接线,确保 GND 相连 |
| 数据丢失 | 缓冲区溢出 | 使用中断或 DMA,增加缓冲区 |
| 偶发错误 | 时钟不准、电磁干扰 | 检查晶振精度,增加屏蔽 |
| 只能发不能收 | 引脚复用未配置 | 检查 GPIO 复用功能设置 |
6.2 调试工具推荐
- 串口助手:SSCOM、XCOM、Putty、SecureCRT
- 逻辑分析仪:Saleae Logic、DSLogic(抓取 UART 波形)
- 示波器:查看 TX/RX 波形,确认波特率和电平
6.3 波特率误差容忍
STM32 波特率发生器允许约 ±2% 的误差,建议实际误差控制在 ±1% 以内。
7. 参考资源
- ST 官方文档 RM0008 - STM32F10xxx 参考手册
- ST 官方文档 UM1725 - STM32Cube HAL 用户手册
- ST 社区 https://community.st.com
- 正点原子 STM32 开发指南
- 野火 STM32 库开发实战指南
结语:UART 是嵌入式开发中最基础、最常用的通信接口。掌握其原理与 STM32 配置方法,是嵌入式开发的必备技能。建议从轮询方式入手,逐步过渡到中断和 DMA,以应对不同场景的需求。