3、UART协议原理:UART帧格式(起始位、数据位、校验位、停止位)、波特率定义与计算

UART(Universal Asynchronous Receiver/Transmitter,通用异步收发器)是单片机系统中最基础、最常用的串行通信协议之一。与SPI、I2C等同步通信协议不同,UART在传输数据时不依赖时钟线,而是通过收发双方预先约定好的波特率(Baud Rate)以及帧格式(Frame Format)来实现数据的可靠传输。理解UART帧的每一位定义、波特率的本质以及误差容限,是编写稳定串口驱动、排查通信故障的基石。本章将深入剖析UART协议的核心原理,从帧格式的每一位说起,再到波特率的计算与误差分析,并结合实际工程案例进行拆解。

UART 异步通信帧结构与信号链路 发送端 MCU UART_TX 发送移位寄存器 TX 物理线路(总线) 空闲态: 高电平 (逻辑1) RX 接收端 MCU UART_RX 接收移位寄存器 UART 帧格式(以 8 数据位、无校验、1 停止位为例) 起始位 0 (低电平) D0 LSB D1 D2 D3 D4 D5 D6 D7 MSB 停止位 1 (高电平) 下一帧 起始位 t0 t0 + 1bit t0 + 5bit t0 + 9bit t0 + 10bit 波特率 = 1 / 位时间 (bit time) 例: 9600 bps → 每位约 104.17 μs

上图展示了UART通信的基本链路与帧结构。发送端MCU通过TX引脚将并行数据转换为串行位流,经过物理线路传输,接收端MCU通过RX引脚接收并还原数据。帧格式中,每一位都有其特定的电平与时间含义,下面我们将逐一深入解析。

3.1 UART帧格式:每一位的职责与设计

UART帧是数据传输的基本单位,其格式定义了线路空闲状态、数据同步方式以及数据完整性校验机制。一个标准的UART帧由起始位(Start Bit)、数据位(Data Bits)、校验位(Parity Bit,可选)和停止位(Stop Bit)组成。理解每一位的作用,是配置串口参数(如8N1、8E1等)的前提。

3.1.1 起始位:通信的“发令枪”

UART是异步协议,线上没有独立的时钟信号。当线路处于空闲状态时,TX引脚保持为高电平(逻辑1)。发送端要开始传输数据时,首先将线路拉低,并保持一个位时间(Bit Time),这个低电平脉冲就是起始位(逻辑0)。

  • 核心作用:接收端通过检测线路上的下降沿(从高到低跳变)来识别起始位,从而与发送端实现帧同步。起始位是每一位数据采样的时间基准点。
  • 工程细节:接收端在检测到下降沿后,并不会立即采样数据位,而是会等待半个位时间(即1/2 Bit Time)后,在起始位的中心点再次采样,确认电平确实为低。这一“二次确认”机制有效防止了线路上的毛刺噪声引起的误触发。
经验提醒:在编写底层驱动时,接收端对起始位的检测应使用“边沿检测+电平确认”的双重逻辑。若仅依赖边沿触发,高频噪声可能导致接收端误认为一帧开始,从而产生乱码。

3.1.2 数据位:传输的核心内容

起始位之后便是数据位,这是实际要传输的信息。数据位的数量通常为5、6、7或8位,其中8位数据(一个字节)最为常用。数据位的传输顺序为从最低有效位(LSB)开始,到最高有效位(MSB)结束。

  • LSB First:例如要发送十六进制数 0x53(二进制 0101 0011),则线上先发送最低位 1,然后是 1、0、0、1、0、1,最后发送最高位 0。
  • 位时间:每一位的持续时间由波特率决定。例如波特率为9600bps时,每位持续约104.17微秒(μs)。

3.1.3 校验位:数据完整性的“守护者”

校验位用于检测数据在传输过程中是否发生错误。它是在数据位之后、停止位之前发送的额外一位。校验方式主要有三种:无校验(None)、奇校验(Odd)和偶校验(Even)。

校验方式 计算规则 示例(数据位 0x53 = 0101 0011)
无校验 (N) 不发送校验位,帧长度缩短1位 无校验位,直接跟停止位
偶校验 (E) 数据位中“1”的个数 + 校验位“1”的个数 = 偶数 数据位中1的个数为4(偶数),校验位为0
奇校验 (O) 数据位中“1”的个数 + 校验位“1”的个数 = 奇数 数据位中1的个数为4(偶数),校验位为1

判断方法:接收端在收到数据位后,会自行计算校验位并与接收到的校验位进行比较。若不一致,则置位错误标志(如USART的PE标志),通知软件处理。

风险说明:校验位只能检测奇数个位错误(如1位、3位翻转),无法检测偶数个位错误。对于可靠性要求极高的工业总线,建议使用更高级的CRC校验,而非仅依赖奇偶校验。

3.1.4 停止位:帧结束的“休止符”

停止位标志着帧的结束,它表现为高电平(逻辑1),持续时间为1位、1.5位或2位(根据配置)。停止位不仅用于分隔相邻的两帧,更重要的是,它保证了下一帧起始位(下降沿)能够被可靠检测——因为起始位是低电平,而停止位是高电平,两者之间必然存在一个明显的下降沿。

  • 常见配置:1位停止位(最常用)、2位停止位(常用于低速或抗干扰场景)。1.5位停止位仅见于某些特定协议(如一些老式电传打字机)。
  • 工程意义:停止位越长,帧间隔越大,接收端处理时间越充裕,但有效数据传输率会降低。

3.2 波特率:通信的“心跳”与计算

波特率(Baud Rate)定义了每秒传输的符号数(Symbols)。在UART中,一个符号即一个位(Bit),因此波特率等同于比特率(bps, bits per second)。波特率决定了每一位的宽度(位时间),是收发双方必须严格匹配的参数。

3.2.1 波特率的本质与位时间

波特率是UART通信的“心跳”频率。收发双方必须使用相同的波特率,否则接收端采样点会逐渐偏移,导致数据错位。位时间(\( T_{bit} \))与波特率(\( B \))的关系为:

位时间 T_bit = 1 / 波特率 B
示例:B = 9600 bps → T_bit = 1/9600 ≈ 104.17 μs
      B = 115200 bps → T_bit = 1/115200 ≈ 8.68 μs

接收端通常在每一位的中心点进行采样,以最大程度避免信号边沿的抖动或失真带来的误判。

3.2.2 波特率发生器与分频计算

在单片机中,波特率通常由内部定时器或专用波特率发生器从系统时钟分频得到。以经典的8051单片机为例,使用定时器1作为波特率发生器时,计算公式为:

波特率 = (2^SMOD / 32) × (定时器1溢出率)
定时器1溢出率 = 系统时钟频率 / (12 × (256 - TH1))
其中 SMOD 为波特率加倍位(PCON寄存器最高位)

对于STM32等现代ARM单片机,波特率寄存器(USART_BRR)的值计算如下:

USARTDIV = 外设时钟频率 (PCLK) / (16 × 目标波特率)
BRR 寄存器值 = 整数部分 << 4 | 小数部分(四舍五入到4位小数)

操作流程:配置波特率时,应先查阅芯片参考手册,确认外设时钟源频率,然后根据目标波特率反推分频系数。若分频结果存在小数,需进行四舍五入,并评估实际波特率与目标值的误差。

3.2.3 波特率误差容限与影响

收发双方的波特率不可能完全一致,总会存在微小偏差。只要偏差在±2%(对于8位数据+1起始+1停止的帧结构)以内,通信通常仍能正常进行。但若偏差过大,接收端在采样后续位时会发生“漂移”,最终导致采样点落在错误的位区间。

帧长度(位) 允许的最大波特率误差(理论值) 工程建议误差范围
10位(8N1) ±4.5% ±2%
11位(8E1/8O1) ±4.0% ±1.5%
12位(8N2) ±3.5% ±1.5%
核心原理:误差的累积效应。假设发送端波特率比接收端快1%,那么发送第1位时,接收端采样点偏移了1%的位时间;发送到第10位(停止位)时,累计偏移已达10%的位时间。若采样点偏移超过50%的位时间,就会采到相邻位的数据,导致帧错误(Framing Error)。

3.3 案例拆解:从波形到数据的排障实战

下面通过一个典型的工程场景,演示如何利用帧格式与波特率知识排查UART通信故障。

背景与现象:某嵌入式设备通过UART与PC通信,PC端串口助手配置为115200, 8, N, 1。设备上电后,PC端收到的是乱码,且字符无规律。

初步分析与假设:乱码通常由三种原因引起:波特率不匹配、帧格式不匹配、电平不匹配(如TTL与RS232)。首先排除电平问题(已确认使用USB转TTL模块)。

关键数据与验证过程:

  1. 检查波特率误差:使用示波器测量设备TX引脚的波形,测量一个完整帧的时长。假设测得一帧(10位)总时长为86.8μs,则实际波特率 = 10 / 86.8μs ≈ 115,207 bps,与目标115200误差仅为0.006%,在容限内。排除波特率问题。
  2. 检查帧格式:观察波形,发现空闲电平为高,起始位为低,停止位为高,符合UART电平定义。但仔细测量数据位,发现数据位只有7位,且停止位为2位。原来设备固件中配置的是7, E, 2(7数据位、偶校验、2停止位)。
  3. 根因定位:PC端配置为8N1,而设备实际发送7E2。PC端将设备的校验位和停止位误认为数据位,导致解析出的字节完全错误。

解决方案与结果:将PC端串口助手配置改为9600, 7, E, 2(与设备匹配),或修改设备固件配置为115200, 8, N, 1。修改后通信恢复正常,数据收发准确无误。

复盘与经验:

  • 排查UART通信问题时,示波器是最高效的工具。直接观察波形,数一数一帧中有多少位,测量每位宽度,即可快速判断波特率与帧格式。
  • 不要假设两端配置一致,务必核对双方的数据位、校验位、停止位和波特率。
  • 在固件中增加帧错误(FE)和噪声错误(NE)中断处理,有助于软件快速感知物理层异常。

3.4 常见误区与总结复盘

在UART协议的理解与应用中,工程师常陷入以下误区,需要特别留意:

  • 误区一:认为波特率越高越好。高波特率意味着更短的位时间,对线路质量、寄生电容、地线干扰更敏感。在长线传输或恶劣电磁环境下,过高的波特率会导致误码率急剧上升。
  • 误区二:忽略校验位的局限性。如前所述,奇偶校验无法检测偶数位错误。在关键控制链路中,应使用基于数据包的校验和(如CRC16/CRC32)。
  • 误区三:停止位越长越可靠。停止位主要提供帧间隔,但过长的停止位会降低有效吞吐量。对于大多数应用,1位停止位足够;2位停止位通常用于时钟精度较差的低速场景。
  • 误区四:采样点固定不变。虽然标准UART在位的中心采样,但一些高级MCU支持配置采样点位置(如STM32的OVER8/OVER16模式),合理配置采样点可提升抗干扰能力。

总结复盘:UART协议的精髓在于“异步”二字——通过起始位同步帧、通过波特率同步位。掌握帧格式的每一位定义,理解波特率的计算与误差容限,是编写健壮串口驱动的基础。在实际项目中,建议遵循以下原则:

  1. 配置明确:在代码中显式定义帧格式宏(如 #define UART_FRAME_8N1),避免魔法数字。
  2. 误差预算:在时钟频率无法整除目标波特率时,务必计算实际误差,并确保在容限范围内。
  3. 硬件流控:对于高速或双向大数据量传输,考虑启用RTS/CTS硬件流控,避免数据溢出。
  4. 调试手段:善用逻辑分析仪或示波器,将协议分析从“猜”变为“看”。