3、UART协议基础:理解UART的异步串行通信原理
UART(Universal Asynchronous Receiver/Transmitter,通用异步收发器)是嵌入式系统中最古老、最基础、也最广泛使用的硬件接口协议之一。与I2C和SPI需要时钟线(SCL/SCK)同步不同,UART仅使用两根数据线(TX和RX)即可实现全双工通信,其核心在于异步——收发双方不共享时钟,而是通过预先约定的波特率(Baud Rate)和帧格式(起始位、数据位、校验位、停止位)来保证数据正确解析。本章将深入剖析UART的帧结构、波特率配置方法、奇偶校验的工程意义,并通过实际案例演示如何排查通信故障。
上图展示了UART通信中最核心的帧结构。发送端在空闲时保持TX线为高电平,当需要发送数据时,先拉低一个bit时间作为起始位,随后依次发送数据位(通常LSB在前),最后拉高至少一个bit时间作为停止位。接收端通过检测起始位的下降沿来同步采样时钟,从而在正确的时刻读取每一位数据。这种设计使得UART无需额外的时钟线,极大简化了硬件连接。
3.1 UART帧结构深度解析
3.1.1 核心原理:每一位都有明确职责
UART的每一帧由五个部分组成,每个部分都有其不可替代的作用:
- 起始位(Start Bit):固定为低电平(逻辑0),持续1个bit时间。接收端通过检测到高→低的跳变沿来判断一帧数据的开始。这是异步通信的“同步信号”。
- 数据位(Data Bits):通常为5~9位,常见配置为8位(一个字节)。数据位从LSB(最低有效位)开始发送,到MSB结束。例如发送十六进制0x55(二进制01010101),实际线上顺序为1→0→1→0→1→0→1→0。
- 奇偶校验位(Parity Bit):可选字段,用于简单的错误检测。奇校验要求数据位+校验位中“1”的个数为奇数;偶校验则要求为偶数。该校验只能检测奇数个bit翻转,无法纠错。
- 停止位(Stop Bit):固定为高电平(逻辑1),持续1、1.5或2个bit时间。停止位不仅标志一帧结束,还保证发送端在下一帧起始位之前有足够的“恢复时间”,避免连续帧之间出现重叠。
- 空闲状态(Idle):TX线保持高电平,表示线路空闲,等待下一帧发送。
理解帧结构的关键在于:起始位是下降沿触发,停止位是高电平恢复。接收端内部有一个波特率发生器,在检测到起始位后,会以16倍波特率的频率采样RX线,取中间3次采样的多数表决值作为该bit的电平,以增强抗干扰能力。
3.1.2 判断方法:如何从波形中识别帧格式
在调试UART通信时,使用逻辑分析仪或示波器观察波形是最直接的方法。以下是判断帧格式的步骤:
- 确认空闲电平:观察无数据传输时TX/RX线的电平,应为高电平(3.3V或5V)。若空闲为低电平,则可能是反逻辑(RS232电平)或线路接反。
- 找到起始位:在波形上寻找一个高→低的跳变,该下降沿即为起始位起点。
- 测量bit时间:从起始位下降沿开始,测量到下一个跳变沿的时间间隔,即为1个bit时间。例如9600bps下,bit时间约为104μs。
- 数数据位:从起始位后开始,按bit时间依次采样,数出数据位的个数(通常为8)。
- 检查校验位和停止位:数据位之后,若有一个额外的bit且其电平满足奇偶校验规则,则为校验位;最后应有一个高电平的停止位。
3.1.3 案例拆解:解析一帧实际数据
假设某温度传感器以9600bps、8N1格式发送数据0x3C(二进制00111100)。线上波形如下:
空闲(高) → 起始位(低) → D0(0) → D1(0) → D2(1) → D3(1) → D4(1) → D5(1) → D6(0) → D7(0) → 停止位(高)
接收端解析过程:
- 检测到下降沿,启动内部采样定时器。
- 等待1.5个bit时间后开始采样第一个数据位(D0),之后每隔1个bit时间采样一次。
- 采样得到8个bit:0,0,1,1,1,1,0,0,按LSB优先排列为00111100,即0x3C。
- 确认停止位为高电平,一帧接收完成。
若接收端配置为19200bps,则其采样间隔为52μs,而发送端实际bit时间为104μs,接收端会在一个bit内采样两次,导致数据完全错乱。这就是波特率不匹配的典型症状——收到乱码或完全无数据。
3.2 波特率:通信的“心跳”
3.2.1 核心原理:波特率与比特率的关系
波特率(Baud Rate)指每秒传输的符号数,在UART中每个符号恰好携带1个bit(二进制电平),因此波特率等于比特率(bps)。常见波特率有9600、19200、38400、57600、115200等。波特率决定了每个bit的持续时间:
bit时间 = 1 / 波特率
例如:9600bps → 1/9600 ≈ 104.17μs
115200bps → 1/115200 ≈ 8.68μs
波特率的本质是收发双方约定的采样时钟频率。发送端按此频率逐bit发送,接收端以16倍或8倍过采样率检测电平变化。若双方波特率误差超过±2%,就会导致采样点偏移,最终出现帧错误或数据错位。
3.2.2 配置方法:MCU中的波特率寄存器设置
在STM32等MCU中,波特率由USART外设的BRR寄存器决定,其计算公式为:
BRR = 外设时钟频率 / (16 × 目标波特率)
例如:APB2时钟为72MHz,目标波特率115200
BRR = 72000000 / (16 × 115200) = 39.06 → 取整为39
实际波特率 = 72000000 / (16 × 39) = 115384.6 bps
误差 = (115384.6 - 115200) / 115200 ≈ 0.16% → 可接受
配置步骤通常包括:
- 使能USART时钟和GPIO时钟,配置TX为复用推挽输出,RX为浮空输入或上拉输入。
- 设置数据字长(8位或9位)、停止位位数、校验位使能。
- 计算并写入BRR寄存器。
- 使能USART,并使能发送或接收中断。
3.2.3 实战场景:多设备波特率适配
在调试一个蓝牙模块(默认9600bps)与MCU(运行在115200bps)通信时,发现数据完全无法解析。排查过程如下:
- 初始现象:MCU发送AT指令,蓝牙模块无响应;逻辑分析仪显示波形杂乱。
- 分析判断:测量波形发现bit时间约为104μs(9600bps),而MCU配置为115200bps(bit时间8.68μs),两者相差12倍。
- 实际操作:将MCU的USART波特率改为9600,重新编译烧录。
- 结果对比:通信恢复正常,蓝牙模块返回“OK”。
- 复盘经验:在连接任何新模块前,务必查阅其数据手册确认默认波特率;若模块支持AT指令,可先发送“AT+BAUD”等命令修改其波特率,再统一到系统标准值。
3.3 奇偶校验:简单但有效的错误检测
3.3.1 核心原理:奇偶校验的数学逻辑
奇偶校验通过在数据位后附加1个校验位,使整个帧(数据位+校验位)中“1”的个数满足预设的奇偶性:
| 校验模式 | 规则 | 示例(数据0x55,二进制01010101) |
|---|---|---|
| 无校验(N) | 不发送校验位 | 帧长度8bit,无额外开销 |
| 奇校验(O) | 数据位+校验位中“1”的总数为奇数 | 0x55有4个“1”,校验位=1,总数为5(奇数) |
| 偶校验(E) | 数据位+校验位中“1”的总数为偶数 | 0x55有4个“1”,校验位=0,总数为4(偶数) |
接收端计算收到的数据位中“1”的个数,与校验位比对。若不一致,则置位错误标志(如PE位)。需要注意的是,奇偶校验只能检测奇数个bit翻转,若两个bit同时翻转(如00→11),则校验仍通过,错误无法发现。
3.3.2 判断方法:何时启用校验位
在实际工程中,是否启用校验位取决于应用场景:
- 短距离、低干扰(如PCB板内通信):通常使用8N1,无校验,减少开销。
- 长线传输或工业环境:建议启用偶校验(8E1),可检测大部分单bit错误。
- 对可靠性要求极高:不应依赖奇偶校验,而应使用CRC或更高层协议(如Modbus RTU自带CRC16)。
启用校验位后,帧长度变为9位(8数据+1校验),此时MCU的数据字长需设置为9位。若配置为8位数据+校验,则实际有效数据只有7位,这在ASCII通信中常见(7E1格式)。
3.3.3 常见误区与总结复盘
误区2:收发双方校验模式不一致。例如发送端配置偶校验,接收端配置无校验,会导致接收端将校验位当作数据位,所有数据错位。
误区3:忽略校验错误标志。MCU的USART外设会记录校验错误,但若未使能错误中断,错误帧会被静默丢弃,造成数据“神秘丢失”。
总结复盘:UART通信的可靠性建立在三个一致上——波特率一致、帧格式一致、电平标准一致。在调试时,应遵循“先查波特率,再查帧格式,最后查硬件连接”的顺序。使用逻辑分析仪观察波形是最直观的排障手段,它能同时显示电平时序和bit解析结果,帮助快速定位问题。
3.4 硬件连接与电平标准
3.4.1 核心原理:TTL与RS-232电平转换
MCU的UART引脚通常输出TTL电平(0~3.3V或0~5V),而PC的串口(DB9)使用RS-232电平(-12V~+12V)。两者不能直接相连,必须通过电平转换芯片(如MAX3232)或USB转TTL模块(如CH340、CP2102)桥接。TTL电平中,高电平(3.3V)代表逻辑1,低电平(0V)代表逻辑0;RS-232则相反,负电压代表逻辑1,正电压代表逻辑0。
连接时需注意交叉连接:发送端的TX接接收端的RX,接收端的RX接发送端的TX,地线(GND)必须共地。若两个设备电平标准不同(如3.3V MCU与5V传感器),需确认是否兼容,必要时加电平转换电路。
3.4.2 操作流程:搭建最小UART通信链路
- 准备两个MCU开发板(或MCU与USB转TTL模块)。
- 将A板的TX接B板的RX,A板的RX接B板的TX,两板GND相连。
- 若使用USB转TTL模块,将模块的TX接MCU的RX,模块的RX接MCU的TX,GND相连。
- 在MCU代码中配置USART为相同波特率和帧格式。
- 发送端循环发送0x55(01010101),接收端在中断中接收并回显到调试串口。
若接收端收到的数据为0xAA(10101010),说明数据位顺序反转(MSB优先),需检查配置;若完全无数据,检查TX/RX是否接反或GND未共地。
3.4.3 案例拆解:RS-485总线上的UART应用
在工业现场,UART常通过RS-485收发器(如MAX485)转换为差分信号,实现远距离(1200米)多点通信。某项目使用RS-485连接10个温湿度传感器,波特率9600,8N1格式。调试中发现第5号传感器数据偶尔丢失。
- 初始现象:主站轮询时,第5号传感器约每10次响应中丢失1次。
- 分析判断:使用示波器观察A/B差分线波形,发现第5号传感器响应时,波形上升沿较缓,且存在振铃现象。推测是终端电阻匹配不当或该节点距离总线末端过近。
- 实际操作:在总线两端各并联一个120Ω终端电阻,并检查第5号传感器的RS-485收发器供电电压(应为3.3V,实测2.8V,偏低)。更换为独立稳压供电后,波形明显改善。
- 结果对比:连续运行24小时,数据丢失率为0。
- 复盘经验:RS-485总线对终端电阻和节点供电敏感,UART协议本身不提供冲突检测,需在应用层设计轮询机制避免多节点同时发送。
3.5 常见故障排查与工程实践
3.5.1 故障排查流程清单
| 故障现象 | 可能原因 | 排查步骤 |
|---|---|---|
| 完全无数据 | TX/RX接反、GND未共地、波特率差异过大 | 1. 用万用表测TX线空闲电平(应为高);2. 交换TX/RX;3. 检查GND连通性 |
| 乱码 | 波特率不匹配、帧格式不一致、电平标准不兼容 | 1. 用逻辑分析仪测bit时间;2. 核对数据位/停止位/校验位配置 |
| 偶发丢字节 | 接收缓冲区溢出、中断优先级低、线路干扰 | 1. 检查RTO(接收超时)中断;2. 增大缓冲区;3. 加屏蔽线或降低波特率 |
| 校验错误频繁 | 线路过长、干扰强、波特率误差大 | 1. 降低波特率;2. 启用偶校验;3. 检查地线环路 |
3.5.2 工程实践建议
- 缓冲区管理:使用环形缓冲区(Ring Buffer)接收数据,配合空闲中断(IDLE)或DMA,避免高波特率下丢数据。
- 波特率自适应:某些模块(如GPS)支持自动波特率检测,MCU可先发送0x55(交替的0和1),通过测量bit时间自动调整。
- 电气隔离:在工业环境中,使用光耦隔离(如6N137)或数字隔离器(如ISO7721)隔离UART信号,防止地环路干扰。
- 调试技巧:在代码中增加“回环测试”功能——将TX和RX短接,自发自收,验证USART外设本身是否正常。
3.6 本章知识结构总结
UART协议的核心可归纳为“一个帧、两个参数、三个一致”:
- 一个帧:起始位+数据位+校验位+停止位,理解每一位的时序作用。
- 两个参数:波特率(决定bit时间)和帧格式(决定数据位长度、校验模式、停止位个数)。
- 三个一致:收发双方的波特率一致、帧格式一致、电平标准一致。