注意其中的加法不进位,减法不借位,类似是异或逻辑。
关于怎样产生CRC,有这样一个算法:
下面为CRC的计算过程:
1.设置CRC寄存器,并给其赋值FFFF(hex)。
2.将数据的第一个8-bit字符与16位CRC寄存器的低8位进行异或,并把结果存入CRC寄存器。
3.CRC寄存器向右移一位,MSB补零,移出并检查LSB。
4.如果LSB为0,重复第三步;若LSB为1,CRC寄存器与多项式码相异或。
5.重复第3与第4步直到8次移位全部完成。此时一个8-bit数据处理完毕。
6.重复第2至第5步直到所有数据全部处理完成。
7.最终CRC寄存器的内容即为CRC值。
modbus的手册上给出了权威的版本:
A procedure for generating a CRC is:
1. Load a 16–bit register with FFFF hex (all 1’s). Call this the CRC register.
2. Exclusive OR the first 8–bit byte of the message with the low–order byte of the 16–bit CRC register, putting the result in the
CRC register.
3. Shift the CRC register one bit to the right (toward the LSB), zero–filling the MSB. Extract and examine the LSB.
4. (If the LSB was 0): Repeat Step 3 (another shift).
(If the LSB was 1): Exclusive OR the CRC register with the polynomial value 0xA001 (1010 0000 0000 0001).
5. Repeat Steps 3 and 4 until 8 shifts have been performed. When this is done, a complete 8–bit byte will have been
processed.
6. Repeat Steps 2 through 5 for the next 8–bit byte of the message. Continue doing this until all bytes have been processed.
7. The final content of the CRC register is the CRC value.
8. When the CRC is placed into the message, its upper and lower bytes must be swapped as described below.
附上一段代码示例
u16 getCRCCode(u8* buf, int len) //生成从buf开始的len个字节的CRC16码
{
int i, j;
u16 crc = (u16)0xffff;
for (i = 0; i < len; i++)
{
crc ^= (u16)buf[i];
for (j = 0; j < 8; j++)
{
if ((crc & 1) != 0)
{
crc >>= 1;
crc ^= 0xA001;
}
else
crc >>= 1;
}
}
return crc;
}