目录
一、核心定义与核心差异(先理清 “是什么”)
二、原理详解(从基础到特化)
1. UART 核心原理(异步串行通信,三者的基础)
(1)UART 帧结构(异步通信的核心规则)
(2)UART 通信流程
2. USART 核心原理(同步模式补充)
(1)USART 同步模式特征
(2)USART 同步 vs 异步对比
3. LPUART 核心原理(低功耗优化)
(1)时钟源优化
(2)低功耗模式支持
(3)低功耗唤醒功能
三、典型用法与选型建议
1. 典型应用场景(按场景选型)
2. 选型核心原则
四、程序案例(STM32 HAL 库,可直接运行)
前置准备
案例 1:UART 异步通信(最常用,串口收发 + 调试输出)
功能说明
1. STM32CubeMX 配置
2. 核心代码(HAL 库)
3. 测试效果
案例 2:USART 同步通信(带时钟线)
功能说明
1. STM32CubeMX 配置
2. 核心代码
3. 测试说明
案例 3:LPUART 低功耗通信(待机唤醒)
功能说明
1. STM32CubeMX 配置
2. 核心代码
3. 测试效果
五、避坑点(新手常犯)
总结
关键点回顾
全面理解 UART、USART、LPUART 的核心工作原理,明确三者的本质差异,掌握各自的典型应用场景,并且通过基于 STM32 的实战程序案例掌握实际使用方法 —— 核心是 “区分差异→原理解析→场景适配→代码落地”,这也是嵌入式开发中串口应用的核心知识点,我会从基础到实战层层拆解,所有案例均基于 STM32 HAL 库(新手易上手)。
一、核心定义与核心差异(先理清 “是什么”)
三者均属于串行通信接口,核心差异在于通信模式和功耗优化,用表格快速区分:
| 接口类型 | 全称 | 核心特征 | 核心差异点 | 硬件资源 |
|---|---|---|---|---|
| UART | Universal Asynchronous Receiver/Transmitter(通用异步收发器) | 仅支持异步串行通信,无时钟线,靠波特率同步 | 只有异步模式,无同步能力 | 最少(TX/RX) |
| USART | Universal Synchronous/Asynchronous Receiver/Transmitter(通用同步异步收发器) | 兼容 UART(异步)+ 支持同步串行通信(带时钟线),功能更全 | 比 UART 多同步模式,支持 SPI/I2S | 多 SCLK 时钟线 |
| LPUART | Low Power UART(低功耗 UART) | 属于 UART 的低功耗优化版本,支持低功耗模式(待机 / 休眠)下的收发 / 唤醒 | 低功耗优先,异步模式,唤醒功能 | 兼容 UART 引脚,时钟源可选低功耗时钟 |
关键结论:
- USART 包含 UART 的所有功能(异步模式),是 “超集”;
- LPUART 是 UART 的 “低功耗特化版”,无同步模式,核心优化功耗;
- 日常说的 “串口” 大多指 UART(USART 工作在异步模式)。
二、原理详解(从基础到特化)
1. UART 核心原理(异步串行通信,三者的基础)
UART 是异步全双工串行通信,“异步” 指收发双方无专用时钟线,靠预设相同的波特率实现同步,核心是 “帧结构” 和 “波特率匹配”。
(1)UART 帧结构(异步通信的核心规则)
一个完整的 UART 帧包含以下部分(可配置):
空闲位(高电平)→ 起始位(1位,低电平)→ 数据位(8/9位)→ 校验位(0/1位,奇/偶/无)→ 停止位(1/1.5/2位,高电平)- 起始位:标识帧开始,低电平触发接收端采样;
- 数据位:核心传输内容(如 8 位对应 1 个字节);
- 校验位:用于检错(小型系统常用 “无校验”,简化配置);
- 停止位:标识帧结束,高电平;
- 波特率:每秒传输的比特数(如 9600、115200),收发双方必须完全一致,否则数据乱码。
(2)UART 通信流程
- 发送端:将并行数据(如 MCU 内部的 8 位数据)按帧结构转为串行信号,通过 TX 引脚发送;
- 接收端:通过 RX 引脚检测起始位,按波特率采样每一位数据,还原为并行数据;
- 核心:无需时钟线,靠波特率同步,硬件自动完成串并转换。
2. USART 核心原理(同步模式补充)
USART 完全兼容 UART 的异步模式,额外支持同步模式,核心差异是 “同步模式带时钟线”。
(1)USART 同步模式特征
- 新增SCLK(同步时钟)引脚:发送端输出时钟,接收端按该时钟采样数据,无需波特率匹配(同步通信无波特率概念);
- 同步优势:传输速率更高(无波特率误差)、抗干扰更强,适合高速 / 高精度通信;
- 同步帧结构:比异步帧多了 “时钟同步位”,时钟线与数据位严格对齐。
(2)USART 同步 vs 异步对比
| 模式 | 时钟线 | 同步依据 | 速率 | 适用场景 |
|---|---|---|---|---|
| 异步 | 无 | 预设波特率 | 中等(≤1M) | 普通串口通信(如调试) |
| 同步 | 有 | 发送端 SCLK 时钟 | 高速(≥1M) | 高速数据传输(如 SPI 替代) |
3. LPUART 核心原理(低功耗优化)
LPUART 本质是 UART(仅异步),针对电池供电 / 低功耗设备做了三大优化:
(1)时钟源优化
支持选择低功耗时钟(LSI/LSE,32.768kHz)作为时钟源,而非高频系统时钟(如 72MHz),大幅降低时钟功耗;
(2)低功耗模式支持
可在 MCU 的 “待机 / 休眠模式” 下工作:
- 接收端:低功耗模式下仍能检测 RX 引脚的起始位,触发 MCU 唤醒;
- 发送端:低功耗模式下快速唤醒并发送数据,完成后立即回到低功耗;
(3)低功耗唤醒功能
当 RX 引脚检测到预设的 “唤醒字符”(如 0x55)或起始位时,自动唤醒 MCU,无需持续运行,降低待机功耗(μA 级别)。
三、典型用法与选型建议
1. 典型应用场景(按场景选型)
| 接口类型 | 核心适用场景 | 选型优先级 | 举例 |
|---|---|---|---|
| UART | 普通异步通信、调试输出、低速数据传输(≤115200 波特率)、无低功耗需求 | 最高 | 串口调试、传感器异步通信、AT 指令交互 |
| USART | 高速同步通信、需要时钟同步的场景、兼容 SPI/I2S(部分 MCU 支持)、替代 UART | 次高 | 高速数据采集、工业设备同步通信 |
| LPUART | 电池供电设备、低功耗物联网终端(NB-IoT/LoRa)、待机唤醒场景、长续航设备 | 低功耗场景优先 | 智能手环、传感器节点、电池供电检测仪 |
2. 选型核心原则
- 优先选 UART(USART 异步模式):满足 90% 的普通串口需求,配置简单;
- 需高速 / 同步 → 选 USART 同步模式;
- 需低功耗 / 电池供电 → 选 LPUART;
- 注意:STM32 中,LPUART 通常只有 1 个(如 STM32L 系列),UART/USART 数量更多(如 STM32F103 有 3 个 USART)。
四、程序案例(STM32 HAL 库,可直接运行)
以 STM32F103C8T6(UART/USART)和 STM32L431(LPUART,低功耗系列)为例,分别实现核心功能。
前置准备
- 开发环境:STM32CubeMX + Keil5/VS Code;
- 配置工具:STM32CubeMX 配置引脚、时钟、串口参数,生成 HAL 库工程;
- 硬件连接:
- UART/USART:TX→PA2,RX→PA3(STM32F103 USART2);
- USART 同步:新增 SCLK→PA4;
- LPUART:TX→PB10,RX→PB11(STM32L431 LPUART1)。
案例 1:UART 异步通信(最常用,串口收发 + 调试输出)
功能说明
实现 UART 异步通信:MCU 通过 USART2(异步模式,即 UART)向电脑串口助手发送数据,接收电脑发送的数据并回显。
1. STM32CubeMX 配置
- 引脚:USART2_TX→PA2,USART2_RX→PA3;
- 模式:Asynchronous(异步);
- 参数:波特率 115200、数据位 8、停止位 1、无校验、全双工;
- 时钟:APB1 时钟 72MHz(STM32F103)。
2. 核心代码(HAL 库)
/* 头文件包含 */ #include "stm32f1xx_hal.h" #include <string.h> /* 全局句柄 */ UART_HandleTypeDef huart2; /* === 1. UART初始化(CubeMX自动生成,无需修改) === */ void MX_USART2_UART_Init(void) { huart2.Instance = USART2; huart2.Init.BaudRate = 115200; // 波特率 huart2.Init.WordLength = UART_WORDLENGTH_8B; // 8位数据位 huart2.Init.StopBits = UART_STOPBITS_1; // 1位停止位 huart2.Init.Parity = UART_PARITY_NONE; // 无校验 huart2.Init.Mode = UART_MODE_TX_RX; // 收发模式 huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;// 无硬件流控 huart2.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart2) != HAL_OK) { Error_Handler(); } } /* === 2. 串口发送字符串(封装函数,方便调用) === */ void UART_SendString(UART_HandleTypeDef *huart, char *str) { HAL_UART_Transmit(huart, (uint8_t*)str, strlen(str), 1000); // 阻塞发送,超时1s } /* === 3. 串口接收数据(中断接收,非阻塞) === */ uint8_t uart_recv_buf[100]; // 接收缓冲区 void UART_Receive_IT_Init(void) { // 开启中断接收,接收1个字节触发中断 HAL_UART_Receive_IT(&huart2, uart_recv_buf, 1); } /* === 4. 中断回调函数(接收完成后执行) === */ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == USART2) { // 回显接收到的字符 HAL_UART_Transmit(&huart2, uart_recv_buf, 1, 100); // 重新开启中断接收(持续接收) HAL_UART_Receive_IT(&huart2, uart_recv_buf, 1); } } /* === 5. 主函数测试 === */ int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART2_UART_Init(); // 初始化中断接收 UART_Receive_IT_Init(); // 发送欢迎语 char welcome[] = "UART异步通信测试:请输入字符,将回显\r\n"; UART_SendString(&huart2, welcome); while (1) { // 主循环无需操作,接收靠中断 HAL_Delay(100); } } /* 错误处理函数(CubeMX自动生成) */ void Error_Handler(void) { __disable_irq(); while (1) { } }3. 测试效果
- 硬件:STM32 PA2/PA3 接 USB 转 TTL 模块,连接电脑串口助手;
- 串口助手配置:115200、8N1、无流控;
- 运行:串口助手显示欢迎语,输入任意字符,STM32 回显该字符。
案例 2:USART 同步通信(带时钟线)
功能说明
实现 USART 同步模式通信:STM32 USART1 作为主设备,输出时钟(SCLK)和数据,接收端按时钟采样(此处用自环测试,SCLK→PA4,TX→PA9,RX→PA10 短接)。
1. STM32CubeMX 配置
- 引脚:USART1_TX→PA9,USART1_RX→PA10,USART1_CK→PA4(SCLK 时钟线);
- 模式:Synchronous(同步);
- 参数:时钟极性(Low)、时钟相位(1Edge)、数据位 8、停止位 1、无校验。
2. 核心代码
/* 全局句柄 */ UART_HandleTypeDef huart1; /* === 1. USART同步模式初始化 === */ 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; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1; // 时钟分频 huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; // 同步模式配置 if (HAL_UART_Init(&huart1) != HAL_OK) { Error_Handler(); } // 启用同步时钟 HAL_UARTEx_EnableClock(&huart1); } /* === 2. 同步发送数据 === */ void USART_Sync_SendData(uint8_t *data, uint16_t len) { HAL_UART_Transmit(&huart1, data, len, 1000); } /* === 3. 主函数测试 === */ int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART1_UART_Init(); uint8_t send_data[] = "USART同步通信测试\r\n"; while (1) { // 同步发送数据 USART_Sync_SendData(send_data, sizeof(send_data)-1); HAL_Delay(1000); } }3. 测试说明
- 同步模式下,PA4 输出时钟信号,PA9 输出数据,示波器可看到时钟与数据严格对齐;
- 接收端需连接 SCLK、TX、RX、GND,无需配置波特率,直接按时钟采样。
案例 3:LPUART 低功耗通信(待机唤醒)
功能说明
STM32L431(低功耗系列)LPUART1 实现低功耗通信:MCU 进入待机模式,LPUART 检测到 RX 引脚的起始位 / 唤醒字符(0x55)时唤醒 MCU,发送响应数据。
1. STM32CubeMX 配置
- 引脚:LPUART1_TX→PB10,LPUART1_RX→PB11;
- 模式:Asynchronous(异步)、低功耗唤醒使能;
- 参数:波特率 9600、8N1、唤醒字符 0x55;
- 电源:启用低功耗模式(Standby)。
2. 核心代码
/* 全局句柄 */ UART_HandleTypeDef hlpuart1; /* === 1. LPUART初始化(低功耗配置) === */ void MX_LPUART1_UART_Init(void) { hlpuart1.Instance = LPUART1; hlpuart1.Init.BaudRate = 9600; hlpuart1.Init.WordLength = UART_WORDLENGTH_8B; hlpuart1.Init.StopBits = UART_STOPBITS_1; hlpuart1.Init.Parity = UART_PARITY_NONE; hlpuart1.Init.Mode = UART_MODE_TX_RX; hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; hlpuart1.Init.ClockPrescaler = UART_PRESCALER_DIV1; hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_WAKEUP_INIT; hlpuart1.AdvancedInit.WakeUpEvent = UART_WAKEUP_ON_ADDRESS; // 唤醒字符触发 hlpuart1.AdvancedInit.AddressDetection = UART_ADDRESS_DETECTION_7B; hlpuart1.AdvancedInit.Address = 0x55; // 唤醒字符0x55 if (HAL_UART_Init(&hlpuart1) != HAL_OK) { Error_Handler(); } } /* === 2. 进入待机模式 === */ void Enter_Standby_Mode(void) { // 禁用所有中断(除LPUART唤醒) HAL_NVIC_DisableIRQ(EXTI0_IRQn); // 配置LPUART唤醒中断 HAL_UART_EnableIT(&hlpuart1, UART_IT_WAKEUP); // 进入待机模式 HAL_PWR_EnterSTANDBYMode(); } /* === 3. LPUART唤醒回调函数 === */ void HAL_UART_WakeupCallback(UART_HandleTypeDef *huart) { if (huart->Instance == LPUART1) { // 唤醒后发送响应 char wakeup_msg[] = "LPUART唤醒成功!\r\n"; HAL_UART_Transmit(&hlpuart1, (uint8_t*)wakeup_msg, strlen(wakeup_msg), 1000); } } /* === 4. 主函数测试 === */ int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_LPUART1_UART_Init(); // 初始发送提示 char init_msg[] = "进入低功耗待机模式,发送0x55唤醒\r\n"; HAL_UART_Transmit(&hlpuart1, (uint8_t*)init_msg, strlen(init_msg), 1000); // 延时后进入待机模式 HAL_Delay(2000); Enter_Standby_Mode(); while (1) { // 唤醒后执行此处 HAL_Delay(1000); Enter_Standby_Mode(); // 再次进入待机 } }3. 测试效果
- 硬件:LPUART1 RX→PB11 接 USB 转 TTL,连接电脑串口助手;
- 串口助手发送 0x55(十六进制),STM32 从待机模式唤醒,发送 “LPUART 唤醒成功!”;
- 功耗:待机模式下 MCU 功耗≤10μA(电池供电可续航数月)。
五、避坑点(新手常犯)
- UART 波特率不匹配:收发双方波特率 / 数据位 / 停止位 / 校验位必须完全一致,否则乱码(优先用 8N1 配置);
- USART 同步模式引脚漏配:同步模式必须连接 SCLK 时钟线,否则无法通信;
- LPUART 低功耗时钟配置:需选择 LSI/LSE 低功耗时钟,否则功耗无法降低;
- 中断接收未重新开启:UART 中断接收完成后,需重新调用
HAL_UART_Receive_IT,否则仅接收 1 次; - 低功耗唤醒条件:LPUART 唤醒需配置正确的唤醒字符 / 触发条件,否则无法唤醒。
总结
关键点回顾
- 核心差异:UART(仅异步)、USART(异步 + 同步)、LPUART(低功耗 UART);
- 选型:普通场景选 UART(USART 异步),高速同步选 USART 同步,低功耗选 LPUART;
- 编程核心:
- UART:配置波特率 / 帧结构,中断 / 阻塞收发;
- USART 同步:新增 SCLK 时钟线配置,无需波特率匹配;
- LPUART:低功耗时钟 + 唤醒条件配置,支持待机唤醒;
- 避坑:波特率匹配、同步时钟线、低功耗时钟是三大核心要点。