1. UART基础:从历史到实战,把串口通信讲透
大家好,我是你们的嵌入式讲师。今天咱们聊聊UART——这个在嵌入式世界里几乎无处不在的通信协议。
说实话,我入行那会儿,调试设备最常用的工具就是串口。一根杜邦线,一个USB转串口模块,再加上逻辑分析仪,基本能解决80%的通信问题。UART看起来简单,但很多新手栽跟头就栽在细节上。咱们今天就把它的底裤扒干净。
1.1 UART协议的历史:老古董,但真香
UART的全称是Universal Asynchronous Receiver/Transmitter,通用异步收发器。这玩意儿诞生于上世纪60年代,比我的年龄都大。
最早是贝尔实验室搞出来的,用于电传打字机和计算机之间的通信。你想想看,那时候的计算机还是房间那么大,通信速率也就几百bps。但UART的设计思想太超前了——它把并行数据转成串行,用一根线就能传数据,省线、省成本。
到了80年代,PC机开始普及,RS-232串口成了标配。我记得当年调试单片机,电脑屁股后面那个9针D型接口就是RS-232。虽然现在新电脑基本不带了,但USB转串口模块满大街都是,几块钱一个,UART的生命力可见一斑。
核心观点:UART之所以能活到现在,不是因为性能多强,而是因为——简单、可靠、成本低。在嵌入式领域,这三个词就是真理。
1.2 异步串行通信原理:没有时钟线,怎么同步?
UART是异步通信,说白了就是发送方和接收方之间没有单独的时钟线。那它们怎么对齐节奏呢?
答案是:双方约定好相同的波特率。
波特率就是每秒传输的符号数。对于UART来说,一个符号就是一个bit。常见的波特率有9600、19200、115200等。我习惯用115200,因为速度快,调试时延迟低。
发送方按照约定的波特率,把数据一位一位地发出去。接收方用同样的波特率采样。只要双方时钟误差在允许范围内(一般是±2%),就能正确通信。
这里有个坑:时钟误差。我曾经在一个项目里,用了两个不同晶振的单片机通信,一个16MHz,一个11.0592MHz。波特率都是115200,但实际误差超过了3%,结果数据全是乱码。后来换成内部RC振荡器校准后才解决。
个人经验:做多机通信时,尽量让所有设备使用同一种时钟源,或者用带自动波特率检测的芯片。否则,你会被时钟误差折磨到怀疑人生。
1.3 数据帧结构:起始位、数据位、校验位、停止位
UART的数据帧是通信的基本单元。一个完整的数据帧长这样:
空闲状态(高电平) → 起始位(低电平) → 数据位(LSB先发) → 校验位(可选) → 停止位(高电平)
咱们拆开来看:
1.3.1 起始位
起始位是一个bit的低电平。它的作用就是告诉接收方:“注意,我要开始发数据了!”
接收方检测到电平从高变低,就知道数据来了,然后启动内部的采样定时器。所以起始位的下降沿是同步的关键。
1.3.2 数据位
数据位是实际传输的数据,一般是5到9位。最常用的是8位数据位,正好一个字节。
注意:UART发送数据时,先发最低位(LSB),再发最高位(MSB)。这一点和I2C、SPI不同,很多新手在这里搞反。
举个例子,发送0x55(二进制01010101),实际线上顺序是:1-0-1-0-1-0-1-0。
1.3.3 校验位
校验位用于简单的错误检测。有三种模式:
| 校验模式 | 说明 | 典型应用 |
|---|---|---|
| 无校验 | 不发送校验位 | 大多数嵌入式通信 |
| 奇校验 | 数据位+校验位中1的个数为奇数 | 老式设备、Modbus |
| 偶校验 | 数据位+校验位中1的个数为偶数 | 某些工业协议 |
我个人习惯用无校验。为什么?因为校验位只能检测奇数个bit错误,而且现在数据链路层都有CRC校验,UART这层的校验意义不大。省下一个bit,能提高有效数据传输率。
1.3.4 停止位
停止位是1个或2个bit的高电平。它的作用是给接收方一个缓冲时间,处理完当前数据帧,准备接收下一帧。
常见的停止位配置:
- 1位停止位:最常用,效率高
- 2位停止位:用于低速设备或噪声环境,给接收方更多时间
- 1.5位停止位:很少见,某些老式设备在用
避坑指南:我曾经在一个项目中,接收端用的是低速单片机,处理中断需要时间。发送端用1位停止位,结果接收端来不及处理,导致数据丢失。后来改成2位停止位,问题解决。所以,如果接收端性能弱,或者通信环境噪声大,用2位停止位更稳妥。
1.4 完整数据帧示例
咱们看一个实际例子:发送0x55(二进制01010101),配置为8N1(8数据位、无校验、1停止位)。
线上波形是这样的:
空闲(高) → 起始(低) → 数据位(LSB先发):1-0-1-0-1-0-1-0 → 停止(高)
用逻辑分析仪抓到的波形,你会看到:一个低电平脉冲(起始位),然后8个高低变化的脉冲(数据位),最后回到高电平(停止位)。
如果你看到波形全是高电平或者全是低电平,那肯定有问题。要么是波特率不匹配,要么是接线错了。
1.5 知识体系结构图
下面这张SVG图,把UART的核心知识点串起来了。你可以把它当作本章的思维导图:
1.6 常见配置参数速查表
最后,给大家一个常用配置速查表。做项目时直接参考:
| 应用场景 | 波特率 | 数据位 | 校验位 | 停止位 | 备注 |
|---|---|---|---|---|---|
| 调试串口 | 115200 | 8 | 无 | 1 | 速度优先 |
| GPS模块 | 9600 | 8 | 无 | 1 | NMEA协议标准 |
| Modbus RTU | 9600/19200 | 8 | 偶校验 | 1 | 工业标准 |
| 蓝牙模块 | 9600~115200 | 8 | 无 | 1 | 看模块手册 |
| 低速传感器 | 2400/4800 | 8 | 无 | 2 | 抗干扰 |