一,关于MODBUS的CRC校验
CRC 域是两个字节,包含一 16 位的二进制值。它由传输设备计算后加入到消息中。接收设备重新计算收到消息的 CRC,并与接收到的 CRC 域中的值比较,如果两值不同,则有误。
在 CRC 计算时只用 8 个数据位,起始位及停止位,如有奇偶校验位也包括奇偶校验位,都不参与 CRC 计算。
CRC 计算方法是:
1、加载一值为 0XFFFF 的 16 位寄存器,此寄存器为 CRC 寄存器。
2、该 16 位寄存器的高位字节与开始 8 位字节进行“异或”运算。运算结果放入这个 16 位寄存器。
3、把 CRC 寄存器的内容右移一位,用 0 填补最高位,并检测移出位是 0 还是 1。
4、如果移出位为零,则重复第三步(再次右移一位);如果移出位为 1,CRC 寄存器与 0XA001进行异或。
5、重复步骤 3 和 4,直到右移 8 次,这样整个 8 位数据全部进行了处理。
6、重复步骤 2 和 5,进行通讯信息帧下一个字节的处理。
7、将该通讯信息帧所有字节按上述步骤计算完成后,得到的 16 位 CRC 寄存器的高、低字节进行交换
8、最后得到的 CRC 寄存器内容即为:CRC 校验码。
二,代码如下
u16 Modbus_CRC16( u8 *puchMsg, u16 usDataLen ) { u8 len = usDataLen -2;//计算数据长度 u16 crc_result = 0xffff;//加载一个16位的寄存器 int crc_num=0; int xor_flag =0; int m=0; int i=0; for( i=0;i<len;i++) { crc_result^=*puchMsg; crc_num =( crc_result&0x0001); for( m=0;m<8;m++) { if(crc_num==1) xor_flag =1; else xor_flag =0; crc_result>>=1; if(xor_flag) crc_result^=0xa001; crc_num=(crc_result&0x0001); } } return crc_result; }