Python_Example_Modbus_CRC协议

 2018-09-09

Author: 楚格

IDE: Pycharm2018.02   Python 3.7   第三方库 crcmod

KeyWord :  CRC modbus    cauCRC 和check

Explain:

1CRC原理

2CRC知识

3CRC代码

 

 

1------------------------------------------------------------------------------------------------------------------

CRC校验:CRC即循环冗余校验码:是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并将得到的结果附在帧的后面,接收设备也执行类似的算法,以保证数据传输的正确性和完整性。
CRC校验原理:其根本思想就是先在要发送的帧后面附加一个数(这个就是用来校验的校验码,但要注意,这里的数也是二进制序列的,下同),生成一个新帧发送给接收端。当然,这个附加的数不是随意的,它要使所生成的新帧能与发送端和接收端共同选定的某个特定数整除(注意,这里不是直接采用二进制除法,而是采用一种称之为“模2除法”)。到达接收端后,再把接收到的新帧除以(同样采用“模2除法”)这个选定的除数。因为在发送端发送数据帧之前就已通过附加一个数,做了“去余”处理(也就已经能整除了),所以结果应该是没有余数。如果有余数,则表明该帧在传输过程中出现了差错。

2------------------------------------------------------------------------------------------------------------------

参考网址

--

>>> <http://www.ip33.com/crc.html >

>>> CRC(循环冗余校验)在线计算

--

>>> < http://crcmod.sourceforge.net/crcmod.predefined.html#predefined-crc-algorithms >

>>>  crcmod.predefined – CRC calculation using predefined algorithms

--

 

 

 

3------------------------------------------------------------------------------------------------------------------

Code:

CRC校验二种方法:

1使用第三方库函数crcmod,但是不够完善,缺少输入输入数据反转处理。

2使用计算法,利用CalCRC16和CheckCRC函数校验输入的byte。先calcuation 后check。

--

__all__ = ["CalCRC16","CheckCRC"]

# ===============================================================
import crcmod
# ===============================================================
def CalCRC16(data, length):
    print(data, length)
    crc=0xFFFF
    if length == 0:
        length = 1
    ## for j in data:
    ##     crc ^= j
    j = 0
    while length != 0:
        crc ^= list.__getitem__(data, j)
        #print('j=0x%02x, length=0x%02x, crc=0x%04x' %(j,length,crc))
        for i in range(0,8):
            if crc & 1:
                crc >>= 1
                crc ^= 0xA001
            else:
                crc >>= 1
        length -= 1
        j += 1
        ##if length == 0:
        ##         break

    return crc
# ===============================================================
def CheckCRC(data, length, crctype):
    if length < 3:
        print('The data len(%d) is less than 3!!!', length)
        return 0
    crc_res = 0
    tmp=[0,0,0,0]

    if crctype == 0:
        crc_res = CalCRC16(data, length-2)
        tmp[0] = crc_res & 0xFF
        tmp[1] = (crc_res >> 8) & 0xFF

        if data[length-2] == tmp[0] and data[length-1] == tmp[1]:
            return 1
    elif crctype == 1:
        print('CRC32 is not support...')

    return 0
# ===============================================================


# ===============================================================
'''
#===============================================================
#   测试专用
#===============================================================
'''
if __name__ == '__main__':

    ## Name Identifier-name, Poly  Reverse Init-value XOR-out Check
    ## ['modbus','CrcModbus',0x18005,REVERSE,0xFFFF,0x0000,0x4B37]
    ## crc16 = crcmod.mkCrcFun(0x18005, rev=True, initCrc=0xFFFF,  xorOut=0x0000) # rev=True,False

    crc16 = crcmod.mkCrcFun(0x18005,  initCrc=0xFFFF,rev=True,  xorOut=0x0000) # rev=True,False
    crc_array = b'0xFE 0xFD'
    crc_calc = crc16(crc_array) #计算得到的CRC
    a=hex(crc_calc)
    print(crc_calc,a)
    print('\n')

    # =========================================
    crc_value = [0x01, 0x04, 0x13, 0x87, 0x00, 0x30]
    crc_transformation = CalCRC16(crc_value,len(crc_value))
    crc_calculation    = hex(crc_transformation)
    # print('crc_calculation:',crc_calculation)
    tasd = [0x00,0x00]
    tasd[0]  = crc_transformation & 0xFF
    tasd[1] = (crc_transformation >> 8) & 0xFF
    H =hex(tasd[0])
    L =hex(tasd[1])
    H_value = int(H,16)
    L_value = int(L,16)
    crc_value.append(H_value)
    crc_value.append(L_value)
    print(crc_value)          # calculation value   CRC

    # ========================================================
    print('\n')
    # crc_value2 = [0x01, 0x04, 0x13, 0x87, 0x00, 0x30,0x44,0xB3]
    # print('crc_value2:',crc_value2)
    # crc_cheak=CheckCRC(crc_value2,len(crc_value2),0)

    crc_check=CheckCRC(crc_value,len(crc_value),0)
    if crc_check == 1:
        print('Right')
    else:
        print('wrong')

    print(crc_check)    # check calculation value

 

 --

Run Result:

--

44877 0xaf4d


[1, 4, 19, 135, 0, 48] 6
[1, 4, 19, 135, 0, 48, 68, 179]


[1, 4, 19, 135, 0, 48, 68, 179] 6
Right
1

Process finished with exit code 0

--

 

 

4------------------------------------------------------------------------------------------------------------------

5------------------------------------------------------------------------------------------------------------------

6------------------------------------------------------------------------------------------------------------------

7------------------------------------------------------------------------------------------------------------------

8------------------------------------------------------------------------------------------------------------------

9------------------------------------------------------------------------------------------------------------------

10------------------------------------------------------------------------------------------------------------------

posted @ 2018-09-09 04:11  楚格  阅读(2528)  评论(0编辑  收藏  举报