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;

}

猜你喜欢

转载自blog.csdn.net/ngany/article/details/85074229