Python对mudbus协议生成CRC16校验算法

Posted 以梦为马&不负韶华

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python对mudbus协议生成CRC16校验算法相关的知识,希望对你有一定的参考价值。

应用场景:

物联网对设备数据采集时,很大一部分都是基于Mudbus协议,使用485或232串口进行连接。
其中Mudbus-RTU消息帧格式的设备,Mudbus报文使用CRC16校验算法。根据设备提供Mudbus协议中的地址位、功能码、起始地址、数据长度得到CRC16校验位。


功能代码:

def mudbus_crc_16(string):
    # 从16进制数组转化为字节数组
    data = bytearray.fromhex(string)
    crc = 0xFFFF
    for pos in data:
        crc ^= pos
        for i in range(8):
            if ((crc & 1) != 0):
                crc >>= 1
                crc ^= 0xA001
            else:
                crc >>= 1
    return hex(((crc & 0xff) << 8) + (crc >> 8))


# mudbus-rtu格式:
# 地址码(2位):03 功能码(2位):06 起始地址(4位,寄存器高地址2位,寄存器低地址2位):00 01 数据长度(4位,数据高地址2位,数据低地址2位):00 0a
issue = '03 06 00 01 00 0a'
# issue为16进制的字符串, 中间有无空格均可
crc = mudbus_crc_16(issue)
print(crc, type(crc))


CRC16 Modbus计算原理:

  1. 预置 1 个 16 位的寄存器为十六进制FFFF(即全为 1) , 称此寄存器为 CRC寄存器。
  2. 把第一个 8 位二进制数据 (通信信息帧的第一个字节) 与 16 位的 CRC寄存器的低 8 位相异或, 把结果放于 CRC寄存器。
  3. 把 CRC 寄存器的内容右移一位( 朝低位)用 0 填补最高位, 并检查右移后的移出位。
  4. 如果移出位为 0, 重复第 3 步 ( 再次右移一位); 如果移出位为 1, CRC 寄存器与多项式A001 ( 1010 0000
    0000 0001) 进行异或。
  5. 重复步骤 3 和步骤 4, 直到右移 8 次,这样整个8位数据全部进行了处理。
  6. 重复步骤 2 到步骤 5, 进行通信信息帧下一个字节的处理。
  7. 将该通信信息帧所有字节按上述步骤计算完成后,得到的16位CRC寄存器的高、低字节进行交换。
  8. 最后得到的 CRC寄存器内容即为 CRC码。

以上是关于Python对mudbus协议生成CRC16校验算法的主要内容,如果未能解决你的问题,请参考以下文章

crc校验码计算方法是啥?

如何计算modbus-rtu的crc校验码

工控常用LRC XOR累加和CRC校验工具校验码自动生成软件多计算方式

CRC校验的位数是如何选取的?

CRC校验

crc32 — 计算一个字符串的 crc32 多项式?