1. 程式人生 > >modbus協議CRC校驗

modbus協議CRC校驗

https://blog.csdn.net/u013625451/article/details/81239572

http://cht.nahua.com.tw/index.php?url=http://cht.nahua.com.tw/software/crc16/&key=Modbus,%20RTU,%20CRC16&title=%E8%A8%88%E7%AE%97%20Modbus%20RTU%20CRC16

 

RTU 檢查碼(CRC)計算, 運算規則如下: 
  • 步驟1: 令 16-bit 暫存器 (CRC 暫存器) = 0xFFFF。
  • 步驟2: Exclusive OR 第一個 8-bit byte 的訊息指令與低位元 16-bit CRC 暫存器, 做 Exclusive OR 將結果存入 CRC 暫存器內。
  • 步驟3: 右移一位 CRC 暫存器, 將 0 填入高位元處。
  • 步驟4: 檢查右移的值, 如果是 0 將步驟3 的新值存入 CRC 暫存器內, 否則 Exclusive OR 0xA001 與 CRC 暫存器, 將結果存入 CRC 暫存器內。
  • 步驟5: 重複步驟3~步驟4, 將 8-bit 全部運算完成。
  • 步驟6: 重複步驟2~步驟5, 取下一個 8-bit 的訊息指令, 直到所有訊息指令運算完成。最後, 得到的 CRC 暫存器的值, 即是 CRC 的檢查碼。值得注意的是 CRC 的檢查碼必須交換放置於訊息指令的檢查碼中。

 

void main(void)
{
	unsigned short tmp = 0xffff;
	unsigned short ret1 = 0;
	unsigned char buff[4] = { 0 };
	buff[0] = 0xB1;
	buff[1] = 0x00;
	buff[2] = 0x00;
	buff[3] = 0x01;

	for (int n = 0; n < 4; n++) {/*此處的6 -- 要校驗的位數為6個*/
		tmp = buff[n] ^ tmp;
		for (int i = 0; i < 8; i++) {  /*此處的8 -- 指每一個char型別又8bit,每bit都要處理*/
			if (tmp & 0x01) {
				tmp = tmp >> 1;
				tmp = tmp ^ 0xa001;
			}
			else {
				tmp = tmp >> 1;
			}
		}
	}
	/*CRC校驗後的值*/
	printf("%X\n", tmp);
	/*將CRC校驗的高低位對換位置*/
	ret1 = tmp >> 8;
	ret1 = ret1 | (tmp << 8);
	printf("ret: %X\n", ret1);
	return 0;

}