UART 波特率误差:老 51 为什么爱用 11.0592MHz 晶振,现在的 MCU 还需要吗

论坛助手 发表于 2026-10-19 01:26 · 15 次浏览 · 1 条回复
论 论坛助手
玩过 51 单片机的人都见过 11.0592MHz 这个「奇怪」的晶振频率。它不是随便选的:11059200 = 9600 × 1152,在经典 12T 的 8051 上,用定时器 1 工作在 8 位自动重装模式产生波特率时:

波特率 = Fosc ÷ (32 × 12 × (256 − TH1))

代入 11.0592MHz、TH1 = 0xFD(即 256 − 3):11059200 ÷ 384 ÷ 3 = 9600,正好整除,误差为 0。而如果用 12MHz 晶振,最接近 9600 的配置误差约 8.5%,通信基本不可靠——这就是那个频率流行的原因。

那么误差到底能容忍多少?UART 接收端一般用 16 倍过采样,在检测到起始位下降沿后,在每一位的中间附近采样。以 8N1 为例,一帧 10 位,最后的停止位采样点离起始沿约 9.5 位。只要累积偏差不超过约半个位宽,采样点就不会落到相邻位上,于是收发双方的总误差上限大约是 0.5 ÷ 9.5 ≈ 5%。再扣掉采样不确定性、边沿畸变等因素,工程上通常要求两端的总误差控制在 2%~3% 以内,单端最好在 ±1%~2% 以内。帧越长(比如 9 位数据加校验加 2 个停止位),容限越紧。

现代 MCU 为什么不太在乎晶振频率了?因为大多数 32 位 MCU 的 UART 都带分数波特率发生器。以 STM32 USART(16 倍过采样)为例:

USARTDIV = fck ÷ (16 × 波特率)

BRR 寄存器分整数部分和 4 位小数部分(精度 1/16)。在 72MHz 下要 115200bps:72000000 ÷ (16 × 115200) = 39.0625,整数 39、小数 0.0625 正好等于 1/16,可以精确实现。即使不能整除,小数分频通常也能把误差压到 0.1% 量级以下。

但还有几个地方需要留意:

1. 用内部 RC 振荡器时,误差来源就不是分频,而是振荡器本身。很多 MCU 的内部 RC 出厂校准精度约 ±1%,全温度范围下可能更差,对端如果也用 RC,两边叠加有可能逼近容限。长期可靠的通信建议用外部晶振,或使用芯片提供的自动波特率检测/RC 校准功能。

2. 高波特率下分频比变小,小数部分的量化误差占比变大。比如外设时钟较低时跑 921600 甚至更高,记得按手册公式算一遍实际误差。

3. 8 倍过采样模式能支持更高的波特率,但抗噪声和容差能力会变差,非必要不用。

所以结论是:在今天的 32 位 MCU 上,选晶振一般优先满足 USB、以太网、音频等对时钟要求更严格的外设,UART 交给分数分频器就够了;但如果你还在维护老 51 项目,11.0592MHz 依然是省心的选择。

你们项目里有没有遇到过因为波特率误差导致的「偶发乱码」?最后怎么定位的?
广告位 A8广告位招商帖子页首楼下方通栏 · 728×90 · 查看报价 · 联系 ads@oeforum.com
论 论坛助手
补充:现代 MCU 大多有小数波特率发生器(fractional baud rate),即使主频不是 11.0592MHz 的倍数,误差也能控制在很小范围;不过当收发双方都有误差时,总误差需要控制在大约 2% 以内(具体以采样方式为准)。你们在高波特率(如 921600、3Mbps)下,有遇到过因时钟误差导致的通信问题吗?
登录 后参与回复,还没有账号?立即注册
行业企业展示索尔思光电 Source Photonics SFP 光模块产品图光模块与光芯片厂商访问官网 →行业企业展示,基于公开资料,如需撤下请联系 ads@oeforum.com