4、UART通信协议详解

UART(Universal Asynchronous Receiver/Transmitter,通用异步收发器)是MCU开发中最基础、最常用的串行通信协议之一。本章深入解析UART的帧格式、波特率计算原理以及硬件流控机制,为后续DMA传输与时钟树配置打下坚实的协议基础。

4.1 UART帧格式

UART通信以“帧”为单位进行数据传输。一个完整的UART帧由起始位、数据位、可选的校验位和停止位组成。通信双方必须约定完全相同的帧格式,才能正确解析数据。

关键概念:UART是异步通信,没有独立的时钟线。接收端通过预先约定的波特率,从起始位的下降沿开始同步,逐位采样数据。

4.1.1 帧结构详解

字段 位宽 电平逻辑 功能说明
空闲位 无限制 高电平(逻辑1) 总线空闲状态,TX线保持高电平
起始位 1位 低电平(逻辑0) 标志一帧开始,接收端据此同步采样时钟
数据位 5~9位(常用8位) LSB先行 实际传输的有效数据,低位在前,高位在后
校验位 0或1位 奇/偶/无 可选,用于简单的错误检测
停止位 1/1.5/2位 高电平(逻辑1) 标志一帧结束,保证下一帧起始位有明确的下降沿
工程经验:最常用的配置是“8N1”——8位数据位、无校验、1位停止位。这种配置在效率和兼容性之间取得了最佳平衡。

4.1.2 UART帧格式SVG图

UART帧格式(8N1配置) 一帧完整数据 空闲 (高) 起始 (低) D0 LSB D1 D2 D3 D4 D5 D6 D7 MSB 停止 (高) 下降沿同步 数据位传输顺序:LSB(最低有效位)→ MSB(最高有效位) 总帧长 = 1起始 + 8数据 + 1停止 = 10位

4.2 波特率计算原理

波特率(Baud Rate)定义了UART每秒传输的符号数。对于UART,一个符号即一个位(bit),因此波特率等于比特率(bps)。波特率的精度直接影响通信的可靠性。

4.2.1 波特率与时钟的关系

MCU内部通过系统时钟分频产生UART模块的工作时钟。波特率计算公式如下:

波特率 = UART时钟频率 / (16 × 分频系数)

其中:
- UART时钟频率:来自系统时钟或外设时钟(如APB时钟)
- 16:过采样率(标准UART使用16倍过采样)
- 分频系数:可配置的整数分频值(通常为16位寄存器,范围1~65535)
常见陷阱:当系统时钟频率不是波特率的整数倍时,会产生波特率误差。误差超过±2%时,接收端可能发生采样错位,导致数据错误。务必在配置后计算实际误差。

4.2.2 波特率误差计算

目标波特率 系统时钟 理论分频值 实际分频值 实际波特率 误差
115200 16 MHz 8.68 9 111111 -3.55% ❌
115200 18.432 MHz 10.00 10 115200 0.00% ✅
9600 16 MHz 104.17 104 9615 +0.16% ✅
9600 8 MHz 52.08 52 9615 +0.16% ✅
工程建议:选择系统时钟频率时,优先考虑能整除常用波特率(如115200、9600)的晶振频率。18.432 MHz、11.0592 MHz、7.3728 MHz是UART通信的“黄金频率”。

4.2.3 波特率配置代码示例

/* STM32 UART波特率配置示例(基于HAL库) */
UART_HandleTypeDef huart1;

void MX_USART1_UART_Init(void)
{
    huart1.Instance = USART1;
    huart1.Init.BaudRate = 115200;          /* 目标波特率 */
    huart1.Init.WordLength = UART_WORDLENGTH_8B;  /* 8位数据位 */
    huart1.Init.StopBits = UART_STOPBITS_1;       /* 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; /* 16倍过采样 */

    if (HAL_UART_Init(&huart1) != HAL_OK)
    {
        Error_Handler();
    }
}

4.3 UART硬件流控(RTS/CTS)

当通信双方处理速度不匹配时,硬件流控通过专用的控制线实现流量管理,防止接收缓冲区溢出。最常用的硬件流控协议是RTS/CTS(Request To Send / Clear To Send)。

4.3.1 RTS/CTS信号定义

信号 方向 有效电平 功能说明
RTS(请求发送) 接收端 → 发送端 低电平有效 接收端准备好接收数据时拉低,通知发送端可以发送
CTS(清除发送) 发送端 ← 接收端 低电平有效 发送端检测到CTS为低时才能发送数据;为高时暂停发送

4.3.2 硬件流控工作流程

  1. 初始状态:接收端RTS输出高电平,发送端CTS输入为高,发送端禁止发送数据。
  2. 接收就绪:接收端缓冲区有空闲空间时,将RTS拉低。
  3. 允许发送:发送端检测到CTS变为低电平,开始发送数据帧。
  4. 缓冲区满:接收端缓冲区即将溢出时,将RTS拉高。
  5. 暂停发送:发送端检测到CTS变为高电平,立即停止发送,等待下一次CTS拉低。

4.3.3 硬件流控连接SVG图

UART硬件流控(RTS/CTS)连接示意图 发送端 (MCU A) TX CTS 接收端 (MCU B) RX RTS 数据线 TX → RX 流控线 RTS → CTS RTS/CTS均为低电平有效:RTS拉低表示“可以发送”,CTS为低表示“允许发送” 接收端通过RTS控制发送端的数据流,防止接收缓冲区溢出

4.3.4 硬件流控 vs 软件流控

对比项 硬件流控(RTS/CTS) 软件流控(XON/XOFF)
额外引脚 需要2根专用控制线 不需要额外引脚
响应速度 硬件电平变化,微秒级响应 需发送特殊字符,毫秒级响应
可靠性 高,不受数据内容影响 低,特殊字符可能与数据冲突
适用场景 高速通信、大数据量传输 低速通信、引脚受限的系统
实现复杂度 MCU硬件自动处理,软件透明 需软件解析特殊字符,增加CPU负担
工程决策:在DMA传输场景中,推荐使用硬件流控。DMA传输速度快,CPU无法及时响应软件流控,而硬件流控由UART外设自动管理,无需CPU干预,能有效防止DMA传输过程中的数据溢出。

4.4 本章小结

  • UART帧格式由起始位(1位低电平)、数据位(5~9位,常用8位)、可选的校验位和停止位(1/1.5/2位高电平)组成。最常用配置为8N1。
  • 波特率由系统时钟经分频得到,计算公式为:波特率 = UART时钟 / (16 × 分频系数)。波特率误差应控制在±2%以内。
  • 硬件流控(RTS/CTS)通过专用控制线实现流量管理,接收端通过RTS信号控制发送端的数据流,有效防止缓冲区溢出,特别适合DMA高速传输场景。