工具

CRC / Modbus 校验计算器

粘贴一段 HEX 帧,立刻算出 CRC-16/MODBUS 与 CRC-16/CCITT-FALSE,并给出 Modbus RTU 上线传输的字节序。串口、RS-485、Modbus 调试对不上校验时,先来这里核一下。

识别到 6 字节
01 03 00 00 00 0A
CRC-16/MODBUSCDC5
poly 0xA001 反射 · init 0xFFFF
CRC-16/CCITT-FALSE0428
poly 0x1021 · init 0xFFFF · 不反射
Modbus RTU 传输字节序(高频坑)

CRC 算出来是 0xCDC5,但 Modbus RTU 上线传输时低字节在前、高字节在后。真正拼进报文、在总线抓包里看到的是:

C5 CD

完整帧 = 你的数据 + C5 CD 01 03 00 00 00 0A C5 CD

全部计算在你浏览器本地完成,不上传任何数据。CCITT-FALSE 按协议惯例高字节在前传输,与 Modbus 相反,接线/组帧时务必以对端设备手册规定的字节序为准。

怎么用

把你要发送的数据字节(不含 CRC 那两位)以十六进制粘进输入框——空格、逗号、0x 前缀、大小写都能识别。 工具会同时给出两种最常用的 CRC16:CRC-16/MODBUS(工业设备、PLC、电表、变频器主流)和 CRC-16/CCITT-FALSE(不少蓝牙、串口、XMODEM 风格协议在用)。先看设备手册要哪一个,再取对应结果。

最关键的是下面那块黄色提示:Modbus RTU 的 CRC 是低字节在前。算出来的 0xHHLL 拼进报文时要写成 LL HH, 工具已经帮你排好这个传输顺序,照着拼就不会错。

CRC 到底在算什么

说人话:CRC 把你整段数据当成一个超长的二进制大数,除以一个约定好的「多项式」,取余数当校验码。 发送方算一遍余数附在帧尾,接收方拿收到的数据再算一遍,两边余数对得上就认为没传错。它的强项是能极高概率地抓出线路上的偶发翻转—— 单比特错误、突发干扰这类串口 / RS-485 最常见的毛病,几乎跑不掉。

难点全在参数。同样叫 CRC-16,多项式、初始值、输入输出要不要按位反射、最后要不要异或,任意一项不同结果就完全不一样。 所以对校验之前,先把这几个参数和对端对齐,别想当然。业界通用的做法是拿字符串 "123456789" 当标准测试向量: CRC-16/MODBUS 应得 0x4B37,CRC-16/CCITT-FALSE 应得 0x29B1——本工具正是用这两个官方 check 值校准的。

Modbus 字节序:最容易翻车的地方

Modbus RTU 帧结构是:从站地址 + 功能码 + 数据 + CRC(2字节)。 有个反直觉的规则一定要记住——

  • 帧里所有 16 位数值(寄存器地址、寄存器值、数量)都是大端:高字节在前。
  • 唯独 CRC 反过来:低字节在前、高字节在后。

举个例子:读保持寄存器帧 01 03 00 00 00 0A,算出 CRC = 0xCDC5, 但真正发到线上的完整帧是 01 03 00 00 00 0A C5 CD——注意末尾是 C5 CD 不是 CD C5。 无数人卡在这里:计算器算得没错,发出去设备却一直回「CRC 校验失败」,就是字节序装反了。本工具把这一步单独拎出来,省得你再手动倒腾。

常见问题

为什么我算出来的 CRC 和设备手册对不上?
CRC 不是只有一种,光是 CRC-16 就有几十个变体,参数(多项式、初始值、是否反射输入输出、最终异或值)差一个结果就全变。工业设备最常用的是 CRC-16/MODBUS(多项式 0xA001 反射、初值 0xFFFF),而很多蓝牙、XMODEM、串口协议用的是 CRC-16/CCITT-FALSE(多项式 0x1021、初值 0xFFFF、不反射)。这个工具两种一起给你,先确认设备手册要的是哪一个再对。还有个常见错误是把 CRC 字段本身也算进去了——CRC 只对它前面的数据字节计算,别把已有的两个 CRC 字节也粘进输入框。
Modbus RTU 的 CRC 到底是大端还是小端?
这是踩得最多的坑。Modbus 协议里除了 CRC,其它所有 16 位量(寄存器地址、寄存器值、数量)都是大端(高字节在前);唯独 CRC 反过来,低字节在前、高字节在后。比如你算出 CRC = 0xCDC5,拼进报文和在总线上抓到的却是 C5 CD。很多人对着计算器抄出 0xCDC5,直接按高字节在前发出去,设备就一直回校验错误。本工具会单独把「传输字节序」那一行标出来,直接照着拼帧就行。
CRC 校验通过就代表数据一定没错吗?
不能这么说,但概率上很可靠。CRC-16 有 16 位校验,理论上能 100% 检出所有单比特错误、所有奇数个比特错误、所有长度不超过 16 位的突发错误;对更长的随机错误,漏检概率约为 1/65536。对串口、RS-485 这种偶发干扰的场景足够用了。但 CRC 是「检错」不是「纠错」,它只告诉你这帧坏了、让你丢弃重发,并不能把错误恢复回来;也防不了蓄意篡改(那是 HMAC 之类的活)。所以 CRC 通过只说明「大概率没传错」,不等于业务逻辑一定对。
CRC-16/CCITT-FALSE 和其它 CCITT 变体有什么区别?
「CCITT」这个名字被滥用得很厉害,市面上至少有四五个都叫 CCITT 的 CRC-16,结果各不相同。本工具实现的是 CRC-16/CCITT-FALSE:多项式 0x1021、初值 0xFFFF、输入输出都不反射、最终不异或,标准校验向量 "123456789" 的结果是 0x29B1。它和初值为 0x0000 的 XMODEM、初值 0x1D0F 的 AUG-CCITT、以及做了反射的 KERMIT 都不一样。选型时别只看「CCITT」四个字,一定要核对多项式和初值这两个关键参数,最稳的办法就是拿 "123456789" 这个业界标准向量去对 check 值。

延伸阅读

想搞清楚这些字节最终怎么在两根线上跑起来,先读 UART 串口通信原理,把起始位、波特率、帧格式讲透; 工业现场更常见的是多机总线,接着看 RS-485 差分总线 里的收发方向控制与终端电阻。 调波特率对不上、算分频误差时,用 进制转换 / 波特率误差计算器 顺手核一下; 选串口引脚别踩雷,配合 ESP32 GPIO 选脚检查器 一起用。 更多硬件底层知识可从 硬件原理库 逐条深挖。