Modbus CRC-16 校验:计算校验码与检查完整 RTU 报文

发布于 2026年9月28日
更新于 2026年10月8日
工具指南
5 分钟阅读

从一条读取请求算出 Modbus CRC-16,说明 0BC4 与 C4 0B 的区别,以及怎样检查已经带有 CRC 的 RTU 报文。

Modbus RTU
CRC-16
报文校验
字节序

Modbus CRC-16 校验:计算校验码与检查完整 RTU 报文

同一条 RTU 请求,CRC 计算器显示 0BC4,串口记录的末尾却是 C4 0B。这两个结果可以同时正确:前者把校验码写成一个 16 位数值,后者按实际传输顺序列出两个字节。核对 CRC 时,除了看数值,还要确认计算器用了哪些输入字节。

下面这条 FC03 请求读取设备 01 从偏移 0000 开始的两个寄存器。把计算前后的内容放在一起,就能看清 CRC 应该加在哪里。

内容字节或数值
参与计算的六个字节01 03 00 00 00 02
16 位 CRC 数值0BC4
报文末尾的 CRC 字节C4 0B
带 CRC 的完整请求01 03 00 00 00 02 C4 0B

计算器里应该填哪一段

打开 RTU CRC 计算器,填入 01 03 00 00 00 02,结果会显示为 C4 0B。这里采用的就是追加到报文末尾的字节顺序。

CRC 要覆盖校验码前面的全部报文字节。开头的设备地址 01 和功能码 03 都在计算范围内,不能只取寄存器数据,也不能只取不含设备地址的 PDU。如果从日志中复制的是完整请求,应先分离末尾已有的两个 CRC 字节;如果还在组装请求,则直接使用尚未添加 CRC 的内容。

空格只是字节分隔符,时间戳、TX: 标签和其他日志列都不属于输入。保留一份原始记录再整理文本,比较容易发现漏字节,或把请求和响应连在一起的情况。改过设备地址、起始偏移或读取数量,也要根据修改后的内容重新计算 CRC。

0BC4 为什么写成 C4 0B

0BC4 的高字节是 0B,低字节是 C4。RTU 规定 CRC 先传低字节,再传高字节,所以报文尾部依次写 C4 0B。这个规则见串行线路指南第 2.5.1.2 节。它只说明 CRC 字段的发送顺序,不能据此把整条报文中每两个字节都交换一次。

对照两个工具的结果时,先看它们显示的是 CRC 数值,还是已经排好顺序的报文字节。一个显示 0BC4,另一个显示 C4 0B,并不足以判断其中一个算错了。

手工计算或核对代码时,CRC 寄存器从 FFFF 开始,依次与输入字节异或;每个字节处理八次右移,移出的最低位为一时,与反向多项式 A001 异或。处理完本例的六个字节后,寄存器值为 0BC4。串行线路指南第 6.2.2 节给出了完整算法。

已经带 CRC 的报文怎样检查

对于 01 03 00 00 00 02 C4 0B 这样的完整记录,可以直接粘贴到 RTU 报文解析器,一起查看请求字段和校验结果。若要手工核对,就取前六个字节重新计算,再把结果按传输顺序与末尾的 C4 0B 比较。

把这八个字节全部送入同一 CRC 算法,会得到余数 0000,按两个字节显示就是 00 00。这可以用于整帧余数检查,但不能把结果再次追加到原报文后面,否则八字节请求就成了十字节。计算器只负责处理输入字节,报文长度和字段是否合理还需要另外检查。

CRC 匹配也不能证明寄存器地址选对了。一个读错寄存器的请求,同样可以带有正确的 CRC。功能码、起始偏移和数量仍要对照设备手册;如果疑问在于 40001 这样的编号如何填写,可接着看寄存器地址指南。如果响应通过校验但读出的值不合理,则先确认它对应哪条请求,再检查数据类型、寄存器顺序、缩放和单位,RTU 读取实操有相应的只读示例。

相关文章

Modbus CRC-16 校验:计算校验码与检查完整 RTU 报文 | ModbusKit