python生成crc校验生成modbus16位校验码

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代码实现

def one_byte_crc(data, crc_data):
    """
    处理一个字节的crc校验环节
    :param data:待处理的数据
    :param crc_data:crc寄存器值,最初始的为0xffff
    :return:
    """
    # 把第一个8位二进制数据(通信信息帧的第一个字节)与16位的CRC寄存器的低8位相异或,把结果放于CRC寄存器。
    crc_data_tmp1 = (get_crc_low(crc_data) ^ data) + (0xff00 & crc_data)
    length = 8
    while True:
        # 把CRC寄存器的内容右移一位(朝低位)用0填补最高位,并检查右移后的移出位。
        # 如果移出位为0,重复第3步(再次右移一位);如果移出位为1,CRC寄存器与多项式A001(1010000000000001)进行异或。
        if is_right_zero(crc_data_tmp1):
            crc_data_tmp2 = (crc_data_tmp1 >> 1)
            crc_data_tmp1 = crc_data_tmp2
            length -= 1
        else:
            crc_data_tmp2 = ((crc_data_tmp1 >> 1) ^ 0xA001)
            crc_data_tmp1 = crc_data_tmp2
            length -= 1
            pass
        if length == 0:
            break
    crc_data = crc_data_tmp1
    # 返回对一个8位数据的crc校验
    return crc_data


def get_crc_low(crc_data):
    """
    16位数据 获取低位数据
    :param crc_data:crc寄存器值
    :return:获取16位数据的低位数据
    """
    return crc_data & 0x00ff


def is_right_zero(check_data):
    """
    测试最右方(最低位)是否为 0
    :param check_data: 待测试的数据
    :return: 0 -> True 1 -> False
    """
    if (check_data & 0x0001) == 0:
        return True
    else:
        return False


def do_crc(data_array, crc_data):
    """
    生成一个由 一个字节的16进制数 组成的列表的crc校验结果
    ! 不是crc校验码
    :param data_array: 一个字节的16进制数 组成的列表
    :param crc_data: 初始的crc寄存器值,为modbus初始为: 0xffff
    :return: crc校验结果
    """
    for data in data_array:
        crc_data = one_byte_crc(data, crc_data)
        pass
    return crc_data


def get_crc_verify_code(crc_data):
    """
    生成crc校验码
    :param crc_data: 16进制数据 列表的 crc校验结果
    :return: crc校验码
    """
    return ((crc_data & 0x00ff) << 8) | ((crc_data & 0xff00) >> 8)


crc = 0xffff
datalist = [0x12, 0x34, 0x56, 0x78]
print(‘进行循环冗余校验结果: 0x{:x}‘.format(do_crc(datalist, crc)))
print(‘生成Modbus 循环冗余校验码: 0x{:x}‘.format(get_crc_verify_code(do_crc(datalist, crc))))

python生成crc校验生成modbus16位校验码

上一篇:Photoshop绘制卡通风格音箱


下一篇:Photoshop 偏暗的手机照片转手绘效果