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------------------------------------------------------------------------------------------------------------------


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM