波特率概念:定义、标准波特率值
聊 UART 调试,绕不开的就是波特率。说白了,波特率就是串口通信的“说话速度”。你讲得快,对方也要能跟上那个节奏,不然就是鸡同鸭讲。
我记得刚入行那会儿,调一块 STM32 的串口,死活收不到正确数据。示波器一量,发现我这边设的是 9600,对面那个模块默认是 115200。嗯,这种低级错误,我相信不止我一个人犯过。
波特率的准确定义
波特率(Baud rate)表示每秒传输的符号数。对 UART 来说,一个符号就是一个 bit(起始位、数据位、校验位、停止位都算)。所以 UART 的波特率通常就等于每秒传输的比特数,单位是 bps。
举个更直观的例子:假设波特率是 9600,那一个 bit 的持续时间就是 1/9600 ≈ 104 µs。接收端就在这个间隔里采样电平。如果两边波特率差太多,采样点就会漂,最后数据就错了。
标准波特率值有哪些
为什么会有标准波特率?因为大部分 UART 都是用晶振时钟分频产生的。为了分频方便,业界就定了一组常用值。下面这个表是我项目里最常用的几个。
| 波特率 (bps) | 位时间 (µs) | 典型应用场景 | 我遇到过的坑 |
|---|---|---|---|
| 1200 | 833.3 | 低速传感器、电力仪表 | 长线缆上还行,但传输慢 |
| 2400 | 416.7 | 老式工业设备 | 和 Modbus 配合时要注意 |
| 4800 | 208.3 | GPS 模块、某些仪表 | — |
| 9600 | 104.2 | 最通用的“安全速度” | 我经常用它做默认调试,兼容性最好 |
| 19200 | 52.1 | 升级的工业控制 | 短距离没问题 |
| 38400 | 26.0 | 蓝牙模块、Wi-Fi 模块常见 | 距离稍长就容易丢包 |
| 57600 | 17.4 | 较快的传感器、调试口 | — |
| 115200 | 8.7 | 最常用的高速标准 | 晶振不准时偏差最多,我曾被坑过一次 |
| 230400 | 4.3 | 短距高速通信 | 对时钟要求高,分频容易有误差 |
| 921600 | 1.1 | 调试 bootloader 用 | 线缆质量差一点就废了 |
你看,115200 是 9600 的 12 倍,分频系数正好是整数,所以很多 MCU 都能精确产生。但如果你用的晶振是 11.0592 MHz 的,那能精确分频出 115200;要是拿 12 MHz 晶振去分,就会有小误差。这个我们后面会细聊。
为什么必须匹配波特率
通信双方如果波特率不一致,接收端采样点会逐渐偏移,最终导致帧错误(Framing Error)或溢出错误。我排查过一根 10 米长的 RS232 线缆,两边都是 9600 设定,但信号畸变严重,接收端实际有效采样率偏移了大约 3%,偶尔丢字节。换了更短屏蔽线就没事了。
波特率偏差的来源
- 晶振(晶体)频率不准: 标称 16 MHz,实际可能是 15.98 MHz。温度变化也会漂移。
- 分频器整除法余数: 比如用 16 MHz 给 115200 分频,整数除不尽,只能取近似,引入固定误差。
- 接收端过采样率: 一般用 16 倍过采样,但对噪声、边沿抖动敏感。
- 通信距离和线缆: 长线缆会拉长信号跳变沿,导致采样点偏移。
下面这张图,就是我个人总结的“波特率产生到匹配的完整链路”,你可以直观看到晶振→分频→UART→对端的流程,以及每个环节都可能引入偏差。
实战:用示波器验证波特率
别全靠软件去算,最可靠的方法是用示波器抓一个 bit 的宽度。我一般这样做:
- 把探头夹在 TX 引脚上,触发设成下降沿。
- 发送一个字节,比如 0x55(二进制 01010101,跳变最多,方便测量)。
- 测量第一个跳变沿到第二个跳变沿的时间间隔——那就是一个 bit 的宽度。
- 反过来算波特率 = 1 / 位宽度(秒)。
// 发送 0x55 的伪代码(8N1)
UART_send_byte(0x55);
// 此时示波器会看到:起始位(0) -> 0 -> 1 -> 0 -> 1 -> 0 -> 1 -> 0 -> 停止位(1)
// 相邻两个跳变沿之间的时间就是位时间
关于“波特率”和“比特率”的误解
有时候会有人把波特率(Baud)和比特率(bps)混为一谈。对于 UART,每个符号只携带 1 个 bit,所以数值相同。但在更复杂的调制技术中(比如 QPSK),一个符号可能携带 2 个 bit,这时波特率就小于比特率了。我们搞嵌入式串口的,基本可以忽略这个区别,处理 UART 时就直接用 bps 当波特率,没毛病。