【留贴记录】micropython用crcmod--更新

最近在折腾树莓派pioc、STM32的micropython,准备做一个RS485接口的ModBus协议的小东东,找了半天也没有crc16-modbus的库,后开网上找了半天,自己攒了一个小程序,因为原来在python里有一个crcmod库很好用,通过研究终于搞定了,特发此帖留个记录。

修订了程序,适用于以下三种形式:

read= '31 32 33 34'
read= '0x31 0x32 0x33 0x34'
read= [0x31,0x32,0x33,0x34]

计算结果如下:

data= [0x31, 0x32, 0x33, 0x34]
CRC16校验: 0X30BA
增加Modbus CRC16校验:>>> [0x31, 0x32, 0x33, 0x34, 0xba, 0x30]
Array: [0x31, 0x32, 0x33, 0x34, 0xba, 0x30]
==========================================
data= 0x31 0x32 0x33 0x34
CRC16校验: 0X30BA
增加Modbus CRC16校验:>>> 0x31 0x32 0x33 0x34 0xBA 0x30
list with 0x: 0x31 0x32 0x33 0x34 0xBA 0x30
==========================================
data= 31 32 33 34
CRC16校验: 0X30BA
增加Modbus CRC16校验:>>> 31 32 33 34 BA 30
list without 0x: 31 32 33 34 BA 30

第一步需要改造_crcfunpy.py如下:

def _get_buffer_view(in_obj):
    if isinstance(in_obj, str):
        raise TypeError('Unicode-objects must be encoded before calculating a CRC')
    mv = memoryview(in_obj)
    #if mv.ndim > 1:
    #   raise BufferError('Buffer must be single dimension') 因为没有ndim属性,这两行注释掉,反正基本用不到
    return mv


def _crc8(data, crc, table):
    mv = _get_buffer_view(data)
    crc = crc & 0xFF
    for x in bytes(mv):                #原来的 mv.tobytes(),替换为bytes(mv),后面的都一样
        crc = table[x ^ crc]
    return crc

def _crc8r(data, crc, table):
    mv = _get_buffer_view(data)
    crc = crc & 0xFF
    for x in bytes(mv):
        crc = table[x ^ crc]
    return crc

def _crc16(data, crc, table):
    mv = _get_buffer_view(data)
    crc = crc & 0xFFFF
    for x in bytes(mv):
        crc = table[x ^ ((crc>>8) & 0xFF)] ^ ((crc << 8) & 0xFF00)
    return crc

def _crc16r(data, crc, table):
    mv = _get_buffer_view(data)
    crc = crc & 0xFFFF
    for x in bytes(mv):
        crc = table[x ^ (crc & 0xFF)] ^ (crc >> 8)
    return crc

def _crc24(data, crc, table):
    mv = _get_buffer_view(data)
    crc = crc & 0xFFFFFF
    for x in bytes(mv):
        crc = table[x ^ (crc>>16 & 0xFF)] ^ ((crc << 8) & 0xFFFF00)
    return crc

def _crc24r(data, crc, table):
    mv = _get_buffer_view(data)
    crc = crc & 0xFFFFFF
    for x in bytes(mv):
        crc = table[x ^ (crc & 0xFF)] ^ (crc >> 8)
    return crc

def _crc32(data, crc, table):
    mv = _get_buffer_view(data)
    crc = crc & 0xFFFFFFFF
    for x in bytes(mv):
        crc = table[x ^ ((crc>>24) & 0xFF)] ^ ((crc << 8) & 0xFFFFFF00)
    return crc

def _crc32r(data, crc, table):
    mv = _get_buffer_view(data)
    crc = crc & 0xFFFFFFFF
    for x in bytes(mv):
        crc = table[x ^ (crc & 0xFF)] ^ (crc >> 8)
    return crc

def _crc64(data, crc, table):
    mv = _get_buffer_view(data)
    crc = crc & 0xFFFFFFFFFFFFFFFF
    for x in bytes(mv):
        crc = table[x ^ ((crc>>56) & 0xFF)] ^ ((crc << 8) & 0xFFFFFFFFFFFFFF00)
    return crc

def _crc64r(data, crc, table):
    mv = _get_buffer_view(data)
    crc = crc & 0xFFFFFFFFFFFFFFFF
    for x in bytes(mv):
        crc = table[x ^ (crc & 0xFF)] ^ (crc >> 8)
    return crc

第二步:__init__.py没用可以删掉;

第三步:自己编一个中间文件CRC_mod.py


'''
计算对应的crc可以用以下语句及crc预设名称,,如增加新的请修改predefined.py文件里的_crc_definitions_table:
crc32func = crcmod.predefined.mkPredefinedCrcFun("crc-32")
也可自定义如下:
crc16 =crcmod.mkCrcFun(0x18005, rev=True, initCrc=0xFFFF, xorOut=0x0000)
    Name                Identifier-name,    Poly            Reverse         Init-value      XOR-out     Check
[   'crc-8',            'Crc8',             0x107,          NON_REVERSE,    0x00,           0x00,       0xF4,       ],
[   'crc-8-darc',       'Crc8Darc',         0x139,          REVERSE,        0x00,           0x00,       0x15,       ],
[   'crc-8-i-code',     'Crc8ICode',        0x11D,          NON_REVERSE,    0xFD,           0x00,       0x7E,       ],
[   'crc-8-1',          'Crc81',            0x11D,          NON_REVERSE,    0xFF,           0x00,       0x7E,       ],
[   'crc-8-itu',        'Crc8Itu',          0x107,          NON_REVERSE,    0x55,           0x55,       0xA1,       ],
[   'crc-8-maxim',      'Crc8Maxim',        0x131,          REVERSE,        0x00,           0x00,       0xA1,       ],
[   'crc-8-rohc',       'Crc8Rohc',         0x107,          REVERSE,        0xFF,           0x00,       0xD0,       ],
[   'crc-8-wcdma',      'Crc8Wcdma',        0x19B,          REVERSE,        0x00,           0x00,       0x25,       ],
[   'crc-16',           'Crc16',            0x18005,        REVERSE,        0x0000,         0x0000,     0xBB3D,     ],
[   'crc-16-buypass',   'Crc16Buypass',     0x18005,        NON_REVERSE,    0x0000,         0x0000,     0xFEE8,     ],
[   'crc-16-dds-110',   'Crc16Dds110',      0x18005,        NON_REVERSE,    0x800D,         0x0000,     0x9ECF,     ],
[   'crc-16-dect',      'Crc16Dect',        0x10589,        NON_REVERSE,    0x0001,         0x0001,     0x007E,     ],
[   'crc-16-dnp',       'Crc16Dnp',         0x13D65,        REVERSE,        0xFFFF,         0xFFFF,     0xEA82,     ],
[   'crc-16-en-13757',  'Crc16En13757',     0x13D65,        NON_REVERSE,    0xFFFF,         0xFFFF,     0xC2B7,     ],
[   'crc-16-genibus',   'Crc16Genibus',     0x11021,        NON_REVERSE,    0x0000,         0xFFFF,     0xD64E,     ],
[   'crc-16-maxim',     'Crc16Maxim',       0x18005,        REVERSE,        0xFFFF,         0xFFFF,     0x44C2,     ],
[   'crc-16-mcrf4xx',   'Crc16Mcrf4xx',     0x11021,        REVERSE,        0xFFFF,         0x0000,     0x6F91,     ],
[   'crc-16-riello',    'Crc16Riello',      0x11021,        REVERSE,        0x554D,         0x0000,     0x63D0,     ],
[   'crc-16-t10-dif',   'Crc16T10Dif',      0x18BB7,        NON_REVERSE,    0x0000,         0x0000,     0xD0DB,     ],
[   'crc-16-teledisk',  'Crc16Teledisk',    0x1A097,        NON_REVERSE,    0x0000,         0x0000,     0x0FB3,     ],
[   'crc-16-usb',       'Crc16Usb',         0x18005,        REVERSE,        0x0000,         0xFFFF,     0xB4C8,     ],
[   'x-25',             'CrcX25',           0x11021,        REVERSE,        0x0000,         0xFFFF,     0x906E,     ],
[   'xmodem',           'CrcXmodem',        0x11021,        NON_REVERSE,    0x0000,         0x0000,     0x31C3,     ],
[   'modbus',           'CrcModbus',        0x18005,        REVERSE,        0xFFFF,         0x0000,     0x4B37,     ],
[   'kermit',           'CrcKermit',        0x11021,        REVERSE,        0x0000,         0x0000,     0x2189,     ],
[   'crc-ccitt-false',  'CrcCcittFalse',    0x11021,        NON_REVERSE,    0xFFFF,         0x0000,     0x29B1,     ],
[   'crc-aug-ccitt',    'CrcAugCcitt',      0x11021,        NON_REVERSE,    0x1D0F,         0x0000,     0xE5CC,     ],
[   'crc-24',           'Crc24',            0x1864CFB,      NON_REVERSE,    0xB704CE,       0x000000,   0x21CF02,   ],
[   'crc-24-flexray-a', 'Crc24FlexrayA',    0x15D6DCB,      NON_REVERSE,    0xFEDCBA,       0x000000,   0x7979BD,   ],
[   'crc-24-flexray-b', 'Crc24FlexrayB',    0x15D6DCB,      NON_REVERSE,    0xABCDEF,       0x000000,   0x1F23B8,   ],
[   'crc-32',           'Crc32',            0x104C11DB7,    REVERSE,        0x00000000,     0xFFFFFFFF, 0xCBF43926, ],
[   'crc-32-bzip2',     'Crc32Bzip2',       0x104C11DB7,    NON_REVERSE,    0x00000000,     0xFFFFFFFF, 0xFC891918, ],
[   'crc-32c',          'Crc32C',           0x11EDC6F41,    REVERSE,        0x00000000,     0xFFFFFFFF, 0xE3069283, ],
[   'crc-32d',          'Crc32D',           0x1A833982B,    REVERSE,        0x00000000,     0xFFFFFFFF, 0x87315576, ],
[   'crc-32-mpeg',      'Crc32Mpeg',        0x104C11DB7,    NON_REVERSE,    0xFFFFFFFF,     0x00000000, 0x0376E6E7, ],
[   'posix',            'CrcPosix',         0x104C11DB7,    NON_REVERSE,    0xFFFFFFFF,     0xFFFFFFFF, 0x765E7680, ],
[   'crc-32q',          'Crc32Q',           0x1814141AB,    NON_REVERSE,    0x00000000,     0x00000000, 0x3010BF7F, ],
[   'jamcrc',           'CrcJamCrc',        0x104C11DB7,    REVERSE,        0xFFFFFFFF,     0x00000000, 0x340BC6D9, ],
[   'xfer',             'CrcXfer',          0x1000000AF,    NON_REVERSE,    0x00000000,     0x00000000, 0xBD0BE338, ],
[   'crc-64',           'Crc64',            0x1000000000000001B,    REVERSE,        0x0000000000000000, 0x0000000000000000, 0x46A5A9388A5BEFFE, ],
[   'crc-64-we',        'Crc64We',          0x142F0E1EBA9EA3693,    NON_REVERSE,    0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x62EC59E3F1A4F00A, ],
[   'crc-64-jones',     'Crc64Jones',       0x1AD93D23594C935A9,    REVERSE,        0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xCAA717168609F281, ],
'''

from binascii import *
from crcmod import *
import predefined

# CRC16-MODBUS
def crc16Add(read):
    if isinstance(read, str):
        arr = read
        # print(type(array))
    else:
        arr=''
        for i in read:
            arr=arr+str(hex(i))[2:]+' '
    crc16 =mkCrcFun(0x18005, rev=True, initCrc=0xFFFF, xorOut=0x0000)
    data = arr.replace(" ", "")
    data = data.replace("0x", "")    
    readcrcout = hex(crc16(unhexlify(data))).upper()
    str_list = list(readcrcout)
    #print(unhexlify(data))
    if len(str_list) < 6:
        str_list.insert(2, '0' * (6 - len(str_list)))  # 位数不足补0
    crc_data = "".join(str_list)
    print('CRC16校验:',crc_data)
    if isinstance(read, str):
        if "0x" in read:
            read = read.strip() + ' ' +'0x'+ crc_data[4:] + ' ' +'0x'+ crc_data[2:4]
        else:
            read = read.strip() + ' ' + crc_data[4:] + ' ' + crc_data[2:4]
        print('增加Modbus CRC16校验:>>>', read)
    else:
        aaa=int('0x'+crc_data[4:],16)
        read.append(aaa)
        aaa=int('0x'+crc_data[2:4],16)
        read.append(aaa)
        print('增加Modbus CRC16校验:>>>','[{}]'.format(', '.join(hex(x) for x in read)))
    return read

# CRC8
def crc08Add(read):
    if isinstance(read, str):
        arr = read
        # print(type(array))
    else:
        arr=''
        for i in read:
            arr=arr+str(hex(i))[2:]+' '
    crc08 =predefined.mkPredefinedCrcFun("crc8")
    data = arr.replace(" ", "")
    data = data.replace("0x", "")
    readcrcout = hex(crc08(unhexlify(data))).upper()
    str_list = list(readcrcout)
    #print(unhexlify(data))
    if len(str_list) < 4:
        str_list.insert(2, '0' * (4 - len(str_list)))  # 位数不足补0
    crc_data = "".join(str_list)
    print('CRC08校验:',crc_data)
    if isinstance(read, str):
        if "0x" in read:
            read = read.strip() + ' ' +'0x'+ crc_data[2:4]
        else:
            read = read.strip() +  ' ' + crc_data[2:4]
        print('增加CRC8校验:>>>', read)
    else:
        aaa=int('0x'+crc_data[2:],16)
        read.append(aaa)
        print('增加CRC8校验:>>>','[{}]'.format(', '.join(hex(x) for x in read)))
    return read
if __name__ == '__main__':
    crc16Add("01 03 00 01 00 02")

第四步:直接调用这个crc_mod.py里面定义的函数即可

import CRC_mod
read= [0x31,0x32,0x33,0x34]
print('data=','[{}]'.format(', '.join(hex(x) for x in read)))
read=CRC_mod.crc16Add(read)
print('Array:','[{}]'.format(', '.join(hex(x) for x in read)))
print('==========================================')
read1='0x31 0x32 0x33 0x34'
print('data=',read1)
print('list with 0x:',CRC_mod.crc16Add(read1))
print('==========================================')
read2='31 32 33 34'
print('data=',read2)
print('list without 0x:',CRC_mod.crc16Add(read2))

运行结果如下:

>>> %Run -c $EDITOR_CONTENT
data= [0x31, 0x32, 0x33, 0x34]
CRC16校验: 0X30BA
增加Modbus CRC16校验:>>> [0x31, 0x32, 0x33, 0x34, 0xba, 0x30]
Array: [0x31, 0x32, 0x33, 0x34, 0xba, 0x30]
==========================================
data= 0x31 0x32 0x33 0x34
CRC16校验: 0X30BA
增加Modbus CRC16校验:>>> 0x31 0x32 0x33 0x34 0xBA 0x30
list with 0x: 0x31 0x32 0x33 0x34 0xBA 0x30
==========================================
data= 31 32 33 34
CRC16校验: 0X30BA
增加Modbus CRC16校验:>>> 31 32 33 34 BA 30
list without 0x: 31 32 33 34 BA 30

软件包下载:

mycropython可用的crcmod-Python文档类资源-CSDN文库

还有一个最精简的crc_16_ModBus:

最精简的crc_16_ModBus-Python文档类资源-CSDN文库 

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值