天天看點

c# modbus RTU CRC16校驗和計算

校驗和算法:

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

代碼:

static ushort CRC16(byte[] pDataBytes)
        {
            ushort crc = 0xffff;
            ushort polynom = 0xA001;

            for (int i = 0; i < pDataBytes.Length; i++)
            {
                crc ^= pDataBytes[i];
                for (int j = 0; j < 8; j++)
                {
                    if ((crc & 0x01) == 0x01)
                    {
                        crc >>= 1;
                        crc ^= polynom;
                    }
                    else
                    {
                        crc >>= 1;
                    }
                }
            }

            return crc;
        }
           

代碼解釋:

1、if ((crc & 0x01) == 0x01) 這行代碼即是判斷最後一位是0還是1

2、^符号為異或位運算,參加運算的兩個位,如果這兩個位的值相同,則異或的結果為0。如果值不同,則結果為1

如:1^1=0,1^0=1

3、>>符号是位右移符号,将二進制表示的位整體向右移動。如:1111向右移動一位後就變成了0111。

4、&符号是邏輯與運算符号,兩個二進制位的值相同,則運算結果為1,不同為0