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图
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 硬件流控工作流程
- 初始状态:接收端RTS输出高电平,发送端CTS输入为高,发送端禁止发送数据。
- 接收就绪:接收端缓冲区有空闲空间时,将RTS拉低。
- 允许发送:发送端检测到CTS变为低电平,开始发送数据帧。
- 缓冲区满:接收端缓冲区即将溢出时,将RTS拉高。
- 暂停发送:发送端检测到CTS变为高电平,立即停止发送,等待下一次CTS拉低。
4.3.3 硬件流控连接SVG图
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高速传输场景。