bg

MODBUS CRC16 校验码在线计算与报文解析(RTU、ASCII、TCP)

粘贴任意十六进制格式的 MODBUS 报文,立即就能看到校验码是否正确、每个字节的含义以及寄存器里的数值。计算器会自动识别 MODBUS RTU、ASCII 和 TCP,按两种字节顺序校验 RTU 的 CRC,校验 ASCII 的 LRC,并为没有校验码的数据补上校验码。它在您的浏览器中运行,不会把任何数据发送出去。

计算器需要 JavaScript。请启用后重新加载页面。

MODBUS 报文或数据

每行一帧,最多 20 行。十六进制字节可用各种常见写法(01 03 00 0A、0103000A、0x01 0x03、#01 #03、01,03 或 {0x01, 0x03}),也可以直接粘贴 MODBUS ASCII 文本帧(:0103...)。协议、方向和校验方式均自动识别。

计算器如何识别报文

每一行都会按各种 MODBUS 格式依次尝试,第一个结构成立的格式胜出:

格式识别方法校验方式
MODBUS TCP第 3、4 字节为 00 00(协议标识符),第 5、6 字节给出后面的字节数无:由 MBAP 报文头代替
MODBUS ASCII行以冒号开头且只包含十六进制字符,可以是文本,也可以是 3A 30 31 ... 这样的字节LRC,最后一个字节
MODBUS RTU最后两个字节是前面各字节的 CRC,低字节在前或高低字节颠倒CRC-16,最后两个字节
没有校验码的数据以上都不是,而长度符合不带校验码的请求或响应计算器给出需要追加的 CRC 和 LRC

请求还是响应,由长度判断。读寄存器的请求总是 6 个字节加校验码;响应则带有字节数。如果功能码 01 到 04 的响应紧跟在其请求的下一行,计算器会用寄存器编号(40001 ...)命名各寄存器,并检查数量是否一致。03 和 04 响应中的寄存器值可按各种类型显示:32 位和 64 位浮点数与整数、文本以及 BCD 日期和时间都会自动识别,适用于任何字节序和字序。

MODBUS CRC 的计算方法

MODBUS RTU 使用 CRC-16/MODBUS:多项式 0x8005 的反射形式(0xA001),初值 0xFFFF,没有最终异或。CRC 覆盖从从站地址到最后一个数据字节的全部字节,发送时低字节在前。对于请求 01 03 00 00 00 0A,CRC 为 0xCDC5,因此完整的帧是 01 03 00 00 00 0A C5 CD。

uint16_t modbus_crc(const uint8_t *buf, size_t len)
{
    uint16_t crc = 0xFFFF;
    for (size_t i = 0; i < len; i++) {
        crc ^= buf[i];
        for (int b = 0; b < 8; b++)
            crc = (crc & 1) ? (crc >> 1) ^ 0xA001 : crc >> 1;
    }
    return crc;   /* 先发送 crc & 0xFF,再发送 crc >> 8 */
}
def modbus_crc(data: bytes) -> int:
    crc = 0xFFFF
    for b in data:
        crc ^= b
        for _ in range(8):
            crc = (crc >> 1) ^ 0xA001 if crc & 1 else crc >> 1
    return crc  # 01 03 00 00 00 0A -> 0xCDC5,发送为 C5 CD

少数设备把两个 CRC 字节反过来发送,高字节在前。这不是标准 MODBUS,但帧本身没有问题;计算器会标记为 CRC 高低字节颠倒,与这类设备通信的软件必须接受这种顺序。MODBUS 测试工具(英文)也能发送 CRC 颠倒的请求。

MODBUS ASCII:LRC

MODBUS ASCII 帧是文本:一个冒号,每个字节写成两个十六进制字符,LRC 再占两个字符,最后是 CR LF。LRC 是冒号和 LRC 之间各字节(不是字符)8 位累加和的二进制补码。对于 01 03 00 00 00 0A,和为 0x0E,所以 LRC 为 F2,整个帧写作 :01030000000AF2,后跟 CR LF。

MODBUS TCP:没有校验码

MODBUS TCP 帧不带 CRC,数据由 TCP 保护。它以 7 字节的 MBAP 报文头开始:响应会重复的事务标识符、协议标识符 0、后面的字节数,以及单元标识符(网关用它作为其后面设备的从站地址)。上面的请求通过 TCP 发送时是 00 01 00 00 00 06 01 03 00 00 00 0A。对每一帧,计算器还会给出其 RTU、ASCII 和 TCP 形式,可以直接复制。

CRC 不对时

原因迹象
线路干扰错误时有时无;电缆较长、没有终端电阻、没有共地
端口设置与设备接近但不相同大部分应答失败;校验位或波特率不对会让每个字节都出错
两台设备使用相同的从站地址应答在总线上冲突
报文复制不完整缺少或重复了某个字节;请用长度和字节数对照
非标准设备CRC 数值正确但高低字节颠倒:计算器会明确提示

更多原因请看串口乱码和常见 COM 口错误页面。

输入格式

十六进制字节可以用空格、逗号、分号、短横线或冒号分隔,也可以不加分隔符:01 03 00 0A、0103000A、01-03-00-0A。支持 0x01、#01、$01、\x01 和 01h 这样的前缀和后缀,也支持 {0x01, 0x03, 0x00, 0x0A} 这样的 C 数组。MODBUS ASCII 帧可以直接以文本粘贴,末尾带不带 CR LF 都可以。每行一帧,最多读取 20 行,因此可以把请求和它的响应一起粘贴进来。粘贴按钮一键把剪贴板中的文本放进输入框;第一次使用时浏览器可能会请求权限。

测试设备或捕获通信数据

计算器处理的是您已有的报文。要从设备获取报文:

常见问题

MODBUS CRC 是怎样计算的?

MODBUS RTU 使用 CRC-16/MODBUS:初值为 0xFFFF,把每个字节异或到低字节,然后右移 8 次,每次移出的位为 1 时与 0xA001 异或。结果低字节在前附加到帧尾。对于 01 03 00 00 00 0A,CRC 为 0xCDC5,发送为 C5 CD。

MODBUS RTU 的 CRC 哪个字节在前?

低字节在前。少数设备高字节在前发送;本计算器能识别这种颠倒的顺序并给出提示。

MODBUS TCP 使用 CRC 吗?

不使用。MODBUS TCP 帧以 7 字节的 MBAP 报文头开始(事务标识符、协议标识符 0、长度、单元标识符),没有校验码,因为 TCP 本身会保护数据。

MODBUS ASCII 的 LRC 是怎样计算的?

把冒号和 LRC 之间的所有字节(从站地址、功能码和数据,按字节而不是按字符)相加,保留低 8 位,再取二进制补码。对于 01 03 00 00 00 0A,和为 0x0E,LRC 为 F2。

为什么我的报文 CRC 对不上?

有字节在传输中被改变(线路干扰、缺少共地或终端电阻),端口设置与设备接近但不相同,两台设备同时应答(RS485 总线冲突),或者报文复制不完整。如果计算器提示 CRC 高低字节颠倒,说明设备使用非标准的字节顺序。

计算器会把我的数据发送到别处吗?

不会。所有计算都在您的浏览器中完成。页面只记录使用了哪些按钮,用于匿名的总体使用统计,不包含报文内容。