3. UART 硬件架构:发送器(TX)、接收器(RX)、波特率发生器、FIFO 缓冲区
UART(Universal Asynchronous Receiver/Transmitter)硬件模块是串行通信的物理基础。理解其内部架构——尤其是发送器、接收器、波特率发生器以及 FIFO 缓冲区的协同工作方式,是编写高效、稳定驱动的前提。本章将逐一拆解这些核心组件,并揭示它们之间的数据流与控制关系。
3.1 整体架构概览
一个典型的 UART 外设内部由四个主要功能块构成:波特率发生器(Baud Rate Generator)、发送器(TX)、接收器(RX)以及FIFO 缓冲区。它们通过内部总线与 CPU 或 DMA 控制器相连,共同完成并行数据到串行比特流的转换。
核心要点:UART 硬件本身不处理协议解析,它只负责电平转换、比特采样和帧格式的硬件实现。协议合规性(如起始位、停止位、校验位)由硬件状态机自动完成。
3.2 发送器(TX)
发送器负责将并行数据(通常为 8 位或 9 位)转换为串行比特流,并按照设定的帧格式(起始位、数据位、校验位、停止位)逐位输出到 TXD 引脚。
3.2.1 发送器内部结构
- 发送移位寄存器(TSR):核心部件,从发送 FIFO 或 CPU 加载数据,并在位时钟驱动下右移输出。
- 发送控制状态机:管理帧格式生成,自动插入起始位(低电平)和停止位(高电平)。
- 发送保持寄存器(THR):当 FIFO 未启用时,CPU 直接写入 THR;启用 FIFO 时,数据先进入 FIFO。
- TX 空标志 / TX 中断:指示发送器是否空闲或 FIFO 是否低于阈值,用于触发下一轮数据写入。
驱动开发提示:在 DMA 模式下,发送器通常配置为“FIFO 空触发 DMA 请求”。驱动需确保 DMA 传输长度与 FIFO 深度匹配,避免下溢(underflow)导致帧错误。
3.2.2 发送时序
发送器在位时钟的下降沿采样数据,在上升沿将数据移位到 TXD 引脚。典型的 8N1 格式(8 数据位、无校验、1 停止位)发送时序如下:
| 阶段 | 电平 | 持续时间 | 说明 |
|---|---|---|---|
| 空闲 | 高电平 | — | 线路空闲状态 |
| 起始位 | 低电平 | 1 位时间 | 同步接收器时钟 |
| 数据位 (LSB first) | 高/低 | 8 位时间 | 从最低有效位开始发送 |
| 停止位 | 高电平 | 1 位时间 | 帧结束,恢复空闲 |
3.3 接收器(RX)
接收器从 RXD 引脚采样串行比特流,检测起始位,逐位接收数据,并组装成并行字节存入接收 FIFO 或 CPU 可读的寄存器。
3.3.1 接收器关键机制
- 起始位检测:接收器以 16 倍(或 8 倍)波特率时钟连续采样 RXD 引脚,检测到高→低跳变后,在中间点再次确认,防止毛刺误触发。
- 位采样:在每个位周期的中间点(如第 8、9、10 个过采样时钟)进行多数表决采样,提高抗干扰能力。
- 接收移位寄存器(RSR):将串行输入逐位移入,组装完成后并行加载到接收 FIFO。
- 错误检测:硬件自动检查帧错误(停止位为低)、奇偶校验错误、溢出错误(FIFO 满时新数据覆盖)。
常见陷阱:接收器的过采样时钟频率必须与波特率发生器严格匹配。如果过采样时钟偏差超过 3%,可能导致采样点偏移到错误位区间,产生帧错误或数据错位。
3.4 波特率发生器
波特率发生器本质上是一个可编程分频计数器,从系统时钟(或外设时钟)分频产生发送和接收所需的位时钟。其计算公式为:
// 波特率计算公式(标准 UART)
BaudRate = ClockFreq / (16 * (UBRR + 1))
// 其中:
// ClockFreq : 系统时钟频率 (Hz)
// UBRR : 波特率寄存器值 (0~65535)
// 16 : 过采样因子(常用 16x,部分支持 8x)
3.4.1 分频器配置示例
| 目标波特率 (bps) | 系统时钟 (MHz) | UBRR 计算值 | 实际波特率 (bps) | 误差 (%) |
|---|---|---|---|---|
| 115200 | 16.000 | 8.68 → 9 | 111111 | -3.55 |
| 115200 | 14.7456 | 7.00 → 7 | 115200 | 0.00 |
| 9600 | 16.000 | 103.17 → 103 | 9615 | +0.16 |
| 921600 | 16.000 | 0.085 → 0 | 1000000 | +8.51 |
关键结论:选择系统时钟频率时,应优先选用能整除目标波特率 × 16 的晶振频率(如 14.7456 MHz、18.432 MHz),以将波特率误差控制在 ±1.5% 以内。误差超过 2% 时,长帧传输(如 9 位数据 + 校验)可能产生不可恢复的帧错误。
3.5 FIFO 缓冲区
FIFO(First In First Out)缓冲区是 UART 硬件中用于缓解 CPU 与串行接口速度不匹配的关键组件。它允许 CPU 或 DMA 以突发方式写入/读取多个字节,而无需每发送或接收一个字节就产生一次中断。
3.5.1 FIFO 的工作模式
| 模式 | 触发条件 | 中断/DMA 请求 | 适用场景 |
|---|---|---|---|
| 非 FIFO (传统) | 每 1 字节 | 每次发送/接收都产生中断 | 低数据率、简单系统 |
| FIFO 中断模式 | 可编程阈值 (1/4, 1/2, 3/4, 满) | 达到阈值时产生中断 | 中等数据率,减少中断频率 |
| FIFO DMA 模式 | FIFO 空/满或达到阈值 | 触发 DMA 请求,无需 CPU 干预 | 高数据率、批量传输 |
3.5.2 发送 FIFO 与接收 FIFO 的差异
- 发送 FIFO:CPU 或 DMA 写入数据,硬件自动从 FIFO 取出并移入发送移位寄存器。当 FIFO 中数据量低于触发阈值时,产生“FIFO 空”中断或 DMA 请求。
- 接收 FIFO:硬件将接收到的字节自动存入 FIFO。当 FIFO 中数据量达到触发阈值时,产生“FIFO 满”中断或 DMA 请求。如果 FIFO 已满而新数据到达,则产生溢出错误。
驱动优化建议:在 DMA 环形缓冲传输实现中,通常将接收 FIFO 触发阈值设置为 FIFO 深度的一半(如 16 字节 FIFO 设为 8 字节触发),以平衡响应延迟与 DMA 传输效率。发送 FIFO 则常设置为“FIFO 空”触发 DMA,确保连续发送。
3.6 硬件组件协同工作流程
以下流程图展示了从 CPU 写入数据到 TXD 引脚输出,以及从 RXD 引脚采样到 CPU 读取数据的完整硬件路径: