1. UART协议基础:从历史到实战
各位同学,咱们今天聊聊UART。说实话,这玩意儿在嵌入式领域太常见了,几乎每个做硬件的工程师都跟它打过交道。但越是常见的东西,越容易出幺蛾子。我见过不少项目,最后卡在串口通信上,查半天发现是协议理解不到位。
UART全称是Universal Asynchronous Receiver/Transmitter,通用异步收发器。名字挺长,说白了就是让两个设备能通过一根线互相说话,而且不需要额外的时钟线。
1.1 UART的历史与演进
UART的历史可以追溯到上世纪60年代。那时候计算机之间通信,用的还是并行接口,线又多又贵。后来人们发现,很多场景下不需要那么高的速度,串行通信更划算。
我记得最早接触UART是在大学实验室,用的还是MAX232这种电平转换芯片。那时候的UART芯片是独立的,比如8250、16550这些。现在嘛,基本上都集成到MCU内部了。
UART的演进有几个关键节点:
- 1960s:早期UART作为独立芯片出现,用于连接电传打字机和计算机
- 1980s:IBM PC使用8250 UART,成为事实标准
- 1990s:16550 UART引入FIFO缓冲区,解决了高速通信丢数据的问题
- 2000s至今:UART集成到SoC和MCU中,成为标配外设
1.2 异步串行通信原理
异步串行通信,核心就一句话:没有独立的时钟线,靠约定的速率和帧格式来同步。
你想想看,两个设备之间只有一根数据线,怎么知道什么时候开始收数据?什么时候算一个字节结束?这就是UART协议要解决的问题。
异步通信的关键在于:
- 空闲状态:数据线保持高电平
- 起始位:拉低电平,告诉接收方"我要开始发数据了"
- 数据位:按位发送,LSB(最低有效位)在前
- 停止位:拉回高电平,表示一个字节传输结束
这里有个容易踩的坑:收发双方必须约定好完全相同的参数。波特率、数据位、校验位、停止位,一个都不能错。我曾经帮一个同事排查问题,折腾了两天,最后发现是发送端设了偶校验,接收端设了无校验。
1.3 数据帧格式详解
一个完整的UART数据帧长这样:
空闲状态 | 起始位 | 数据位(5~8位) | 校验位(可选) | 停止位(1/1.5/2位) | 空闲状态
高电平 | 0 | LSB...MSB | 0/1/无 | 1/1.5/2 | 高电平
咱们拆开来看:
起始位
起始位永远是低电平,持续一个位时间。接收方检测到电平从高变低,就知道数据要来了。这个下降沿就是同步信号。
数据位
数据位可以是5、6、7或8位。现在绝大多数场景都用8位。发送顺序是LSB在前,MSB在后。举个例子,发送0x55(二进制01010101),实际线上先发1,再发0,交替进行。
校验位
校验位用于简单的错误检测,有三种模式:
| 校验模式 | 说明 | 典型应用 |
|---|---|---|
| 无校验(None) | 不发送校验位,帧长度最短 | 大多数嵌入式场景 |
| 奇校验(Odd) | 数据位+校验位中1的个数为奇数 | 老式设备、某些工业协议 |
| 偶校验(Even) | 数据位+校验位中1的个数为偶数 | Modbus RTU等 |
停止位
停止位是高电平,持续1、1.5或2个位时间。停止位的作用是给接收方一个缓冲,处理完刚收到的字节。现在大多数场景用1位停止位就够了。
1.4 波特率的概念与计算
波特率,说白了就是每秒传输的符号数。在UART中,一个符号就是一个位,所以波特率就等于比特率。
常见的波特率有:9600、19200、38400、115200、921600等。115200是目前最常用的,速度适中,稳定性好。
波特率的计算公式:
波特率 = 系统时钟频率 / (16 × 分频系数)
以STM32为例,如果系统时钟72MHz,要得到115200波特率:
分频系数 = 72000000 / (16 × 115200) ≈ 39.0625
取整为39,实际波特率 = 72000000 / (16 × 39) ≈ 115384
误差 = (115384 - 115200) / 115200 ≈ 0.16%
误差在±2%以内通常没问题。但要注意,如果系统时钟不是整数倍,误差会累积。我见过一个案例,某款MCU用8MHz晶振,要产生250000波特率,误差达到3.5%,结果通信时断时续。
1.5 UART帧结构SVG图
下面这张图展示了完整的UART数据帧结构,我建议你把它存下来,调试时对照着看:
1.6 常见波特率与误差表
下面这张表列出了常用波特率在不同系统时钟下的分频系数和误差,调试时可以直接参考:
| 目标波特率 | 系统时钟16MHz | 系统时钟72MHz | 系统时钟100MHz |
|---|---|---|---|
| 9600 | 104 (0.16%) | 468 (0.08%) | 651 (0.02%) |
| 19200 | 52 (0.16%) | 234 (0.08%) | 325 (0.02%) |
| 115200 | 8 (0.00%) | 39 (0.16%) | 54 (0.08%) |
| 921600 | 1 (0.00%) | 4 (0.00%) | 6 (0.00%) |