2. UART硬件原理:帧格式、波特率生成、接收移位寄存器与FIFO缓冲区

UART(Universal Asynchronous Receiver/Transmitter)是嵌入式系统中最基础的串行通信外设。理解其硬件数据路径,是优化中断服务函数、解决接收超时与粘包问题的前提。本节从物理帧格式出发,逐级深入波特率时钟、移位寄存器与FIFO缓冲区的协同工作机理。

2.1 UART帧格式:异步传输的物理契约

UART采用异步串行通信,收发双方无需共享时钟信号,而是通过约定的帧格式与波特率完成数据同步。一个标准UART帧包含以下字段:

字段 位宽 电平状态 功能说明
起始位 1 bit 低电平(0) 标志数据帧开始,接收端检测到下降沿后启动采样
数据位 5~9 bit(常用8 bit) LSB first 承载有效载荷,通常为1字节数据
校验位 0/1 bit 奇/偶校验 可选,用于检错(奇校验/偶校验/无校验)
停止位 1/1.5/2 bit 高电平(1) 帧结束标志,保证帧间有至少1 bit的高电平间隔
关键点:起始位的下降沿是接收端时钟同步的参考点。接收端以波特率时钟的16倍或8倍过采样,在每位的中点附近采样,以避开信号跳变沿的噪声区域。
UART帧格式时序图(8N1) UART帧格式时序图(8N1:8数据位 + 无校验 + 1停止位) 空闲 起始位 D0 D1 D2 D3 D4 D5 D6 D7 停止位 采样点 接收端在每位中点采样,起始位下降沿触发同步,停止位保证帧间隔

2.2 波特率生成:从系统时钟到位时钟

波特率(Baud Rate)定义每秒传输的符号数。对于UART,1波特 = 1 bit/s。波特率生成器通常由一个分频计数器实现:

// 波特率计算公式(以STM32 USART为例)
// Tx/Rx 波特率 = f_CK / (16 * USARTDIV)
// 其中 f_CK 为外设时钟,USARTDIV 为16位分频系数(整数+小数部分)

uint32_t baudrate = 115200;
uint32_t usartdiv = (f_CK + (baudrate * 8)) / (baudrate * 16);  // 四舍五入
USART->BRR = usartdiv;
工程要点:波特率误差必须控制在 ±2% 以内,否则累积位偏移会导致帧错误。常用波特率(9600、19200、115200、921600)对应的分频系数应优先选择整数分频,避免小数分频引入的量化误差。
UART波特率生成时钟树 UART波特率生成时钟树 系统时钟 f_CK 分频计数器 位时钟 f_BAUD ÷ (16×USARTDIV) Tx/Rx 采样 分频系数 USARTDIV = f_CK / (16 × 目标波特率),误差需 < 2%

2.3 接收移位寄存器:串行到并行的转换核心

接收移位寄存器(Receive Shift Register, RSR)是UART接收路径的第一级硬件单元。其工作流程如下:

  1. 起始位检测:RX线检测到下降沿后,启动内部采样时钟。
  2. 位采样:在每个位的中点,将RX线上的电平值移入RSR。
  3. 帧校验:接收完停止位后,硬件自动校验起始位、校验位、停止位是否正确。
  4. 数据转移:校验通过后,RSR内容并行加载到接收数据寄存器(RDR),并置位RXNE(Receive Data Register Not Empty)标志。
常见陷阱:如果RSR正在接收下一帧数据时,上一帧数据尚未从RDR中读出(即RXNE标志未清除),则会发生溢出错误(Overrun Error, ORE)。此时新数据会覆盖RDR,旧数据永久丢失。FIFO缓冲区正是为解决此问题而设计。
UART接收移位寄存器数据流 UART接收移位寄存器数据流 RX 引脚 接收移位寄存器 (RSR) 接收数据寄存器 (RDR) FIFO 缓冲区 帧校验 + RXNE 置位 RSR逐位移入 → 帧校验通过后并行加载到RDR → RXNE=1 → DMA或CPU读取 → 数据进入FIFO 若RDR未及时读取,下一帧数据到达时产生溢出错误(ORE)

2.4 FIFO缓冲区:硬件级流量平滑

FIFO(First In First Out)缓冲区是位于RDR与系统总线之间的硬件队列,用于解耦外设接收速率与CPU读取速率。现代MCU的UART外设通常集成深度为16字节或32字节的FIFO。

特性 无FIFO(传统UART) 有FIFO(增强型UART)
中断频率 每接收1字节触发1次中断 可配置触发阈值(如1/4/8/14字节)
CPU负载 高(频繁进出ISR) 低(批量处理)
抗粘包能力 弱(需软件逐字节判断) 强(可配合超时计数器实现帧边界检测)
溢出风险 高(CPU响应延迟时丢数据) 低(FIFO提供缓冲深度)
典型应用 低速、简单协议 高速、复杂协议、多任务系统
优化策略:在RTOS环境中,将FIFO触发阈值设置为FIFO深度的一半(如16字节FIFO设为8字节触发),配合DMA传输,可实现“零中断”接收模式——仅在DMA传输完成或超时时产生一次中断,极大降低CPU占用率。
UART FIFO缓冲区工作状态 UART FIFO缓冲区工作状态(深度16字节) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 写指针 读指针 触发阈值(8字节) 当前状态:已写入9字节(索引0~8),读指针在4,写指针在9 绿色区域:已写入但未读取(待处理数据) 蓝色区域:最新写入位置(写指针指向) 当FIFO中数据量达到触发阈值(8字节)时,硬件自动产生中断或DMA请求

2.5 硬件数据路径总结

从RX引脚到CPU读取,UART接收数据经过以下硬件路径:

  1. RX引脚 → 接收信号调理(施密特触发器、电平转换)
  2. 波特率时钟域同步 → 过采样(通常16倍)与位边界检测
  3. 接收移位寄存器(RSR) → 逐位串行输入,并行输出
  4. 帧校验逻辑 → 校验起始位、校验位、停止位,生成错误标志(FE/PE/ORE/NF)
  5. 接收数据寄存器(RDR) → 保存校验通过后的完整字节
  6. FIFO缓冲区 → 硬件队列,可配置触发阈值
  7. 系统总线接口 → CPU/DMA通过APB/AHB总线读取FIFO数据