工具

进制换算 + 波特率误差计算器

HEX / DEC / BIN 一键互转带 ASCII 视图;再算一算你的晶振跑目标波特率会有多大误差,别等接上串口才发现乱码。

进制换算 · HEX / DEC / BIN + ASCII

FF
十六进制 HEX
255
十进制 DEC
11111111
二进制 BIN
\xFF
ASCII(按字节)

ASCII 一列把数值按字节还原成字符:可打印字符原样显示,不可打印的用 \xNN 占位,方便你核对串口里收到的那串 HEX 到底是什么文本。

UART 波特率误差 · 分频取整

9
分频值 divisor
111,111.11
实际波特率
-3.55%
误差

这个时钟下分频器只能取 9,于是实际跑出来的是 111,111.11 而不是你要的 115,200, 偏差 -3.55%。 经验上收发两端累计误差控制在 ±2% 以内比较稳,超过 3% 就容易出现偶发乱码或丢帧。当前判断: 不推荐(>3%,容易丢帧)

采用 UART 常见的 16 倍过采样:divisor = round(clk / (16 × baud)),实际波特率 = clk / (16 × divisor)。误差来自 divisor 只能取整——这正是「16MHz 晶振跑 115200 会翻车、1.8432MHz 系列晶振却零误差」的原因。全部计算在本地完成。

怎么用

上半部分是进制换算:先选你手里的数值是按哪种进制写的(HEX / DEC / BIN),填进去,四个格子立刻给出另外几种进制和 ASCII 解码。 调串口看到一串 41 42 43 不知道是啥?填 HEX,ASCII 列告诉你是 “ABC”。

下半部分是波特率误差:填上你的时钟源频率(晶振或芯片 APB 时钟,可点预设)和目标波特率, 工具按 UART 常见的 16 倍过采样算出分频器只能取的整数、由此得到的实际波特率,以及跟目标值的偏差百分比。误差在 ±2% 内一般稳,超过 3% 就要换晶振或换波特率了。

为什么波特率会有误差(分频取整)

UART 的波特率不是凭空产生的,而是拿芯片主时钟分频得来。分频器是个整数计数器,公式是 divisor = round(时钟 / (16 × 波特率))——那个 16 是过采样倍数,芯片在每个数据位里采样 16 次来找准中点。 问题就出在 divisor 必须取整:如果时钟除下来不是整数,被截掉的那点小数就变成了波特率误差。

举个最典型的反面例子:16MHz 晶振跑 115200。16000000 ÷ (16 × 115200) = 8.68,取整成 9, 实际波特率变成 16000000 ÷ (16 × 9) ≈ 111111,误差 -3.55%。收发两端各偏一点,累计就顶穿了 UART 的容忍度,表现为偶发乱码、丢字节——而且时好时坏最难查。

反过来,1.8432MHz 系列晶振(3.6864 / 7.3728 / 11.0592 / 14.7456MHz…)之所以在嵌入式圈子里长盛不衰,就是因为它们能被 9600、115200 这些标准波特率整除,误差是干干净净的 0。 现代芯片时钟频率高(ESP32 的 80MHz、STM32 的 72MHz),分频后余数占比小,误差也能压到 1% 以内,所以整 MHz 晶振也能用了——但低成本 8 位机上,选对晶振依然是省心的关键。

常见问题

为什么波特率会有误差,它到底从哪来?
UART 没有独立的高精度时钟,它是从芯片主时钟(晶振或 APB 时钟)分频出来的。分频器只能取整数:divisor = round(时钟频率 / (16 × 目标波特率))。这个「16」是常见的过采样倍数(每个 bit 采样 16 次来对齐)。因为 divisor 必须是整数,除不尽的部分就被截掉了,于是实际跑出来的波特率 = 时钟 / (16 × divisor),跟你要的目标值差那么一点。差多少完全取决于你的时钟频率能不能被整除。
16MHz 晶振跑 115200 到底行不行?
不太行。算一下:16000000 / (16 × 115200) = 8.68,取整成 9,实际波特率 = 16000000 / (16 × 9) = 111111,误差约 -3.55%。收发两端各偏一点,累计很容易超过 UART 能容忍的范围(一般单端 ±2%、双端合计 ±3% 左右是安全线),表现为偶发乱码、丢字节。这就是为什么很多老 8051/AVR 开发板不用整 MHz 晶振,而用 11.0592MHz、14.7456MHz 这类「怪频率」——它们能被常见波特率整除,误差是 0。
那哪些时钟跑 115200 是安全的?
两类:一是能整除的专用波特率晶振,1.8432MHz 及其倍数(3.6864 / 7.3728 / 11.0592 / 14.7456 / 18.432MHz)对 115200 都是零误差;二是频率足够高、分频后余数占比很小的时钟,比如 ESP32 的 APB 80MHz 跑 115200 误差约 +0.93%、STM32 常用 72MHz 也在 1% 内。工具里点一下预设就能对比。低速率(9600)对时钟宽容得多,几乎什么晶振都能凑合。
ASCII 那一列有什么用?
调串口时你经常看到设备回一串 HEX,比如 41 42 43,光看数字不知道是啥。把它填进来,ASCII 列会告诉你那是 "ABC"。不可打印的字节(比如 0D 0A 这种回车换行、或校验字节)用 \x0D 这样的占位显示,方便你区分「这是文本内容」还是「这是控制/协议字节」。逆过来,想知道某个字符的编码,切到十进制或直接查也行。

延伸阅读

想搞懂串口通信本身,读 UART 串口是怎么工作的; 想弄明白晶振和时钟为什么这么关键,看 晶振与时钟原理。 常一起用的还有本站 电池续航估算器PWM / 定时器频率计算器——同样是「分频取整」这套思路。 更多工具在 GPIO 选脚检查器 等页面,硬件原理系统整理在 原理库