在CRC计算时只用8个数据位,起始位及停止位,如有奇偶校验位也包括奇偶校验位,都不参与CRC计算。
CRC计算方法是:
1、 预置1个16位的寄存器为十六进制FFFF(全1),此寄存器为CRC寄存器
unsigned short wcrc = 0xFFFF; //16位CRC寄存器预置
2、 把第一个8位二进制数据(即通讯信息帧的第一个字节)与16位的CRC寄存器的低八位相异或,把结果存放于CRC寄存器。
temp = *buffer & 0x00FF; //将八位数据与crc寄存器亦或 buffer++; //指针地址增加,指向下个数据 wcrc ^= temp; //将数据存入crc寄存器
3、 把CRC寄存器的内容右移一位(朝低位)用0填补最高位,并检测右移后的移出位。
4、 如果移出位为零,则重复第三步(再次右移一位);如果移出位为1,CRC寄存器与多项式A001进行异或。
5、 重复步骤3和4,直到右移8次,这样整个8位数据全部进行了处理。
for (j = 0; j < 8; j++) //循环计算数据的 { if (wcrc & 0x0001) //判断右移出的是不是1,如果是1则与多项式进行异或。 { wcrc >>= 1; //先将数据右移一位 wcrc ^= 0xA001; //与上面的多项式进行异或 } else //如果不是1,则直接移除 { wcrc >>= 1; //直接移除 } }
6、 重复步骤2和5,进行通讯信息帧下一个字节的处理。
7、 将该通讯信息帧所有字节按上述步骤计算完成后,得到的16位CRC寄存器的高、低字节进行交换
8、 最后得到的CRC寄存器内容即为:CRC校验码。
附完整代码如下:
#include<stdio.H> #include<stdlib.H> unsigned short GetCRCData(unsigned char *buffer,unsigned len) { unsigned short wcrc = 0xFFFF; //16位CRC寄存器预置 unsigned char temp; unsigned i = 0, j = 0; //计数 for (i = 0; i < len; i++) //循环计算每个数据 { temp = *buffer & 0x00FF; //将八位数据与crc寄存器亦或 buffer++; //指针地址增加,指向下个数据 wcrc ^= temp; //将数据存入crc寄存器 for (j = 0; j < 8; j++) //循环计算数据的 { if (wcrc & 0x0001) //判断右移出的是不是1,如果是1则与多项式进行异或。 { wcrc >>= 1; //先将数据右移一位 wcrc ^= 0xA001; //与上面的多项式进行异或 } else //如果不是1,则直接移除 { wcrc >>= 1; //直接移除 } } } unsigned char CRC_L,CRC_H; //定义数据高低位 CRC_L = wcrc & 0xFF; //CRC的低8位 CRC_H = wcrc >> 8; //CRC的高8位 return((CRC_L << 8) | CRC_H); } int main(void) { unsigned short crc; unsigned char buffer[6]; buffer[0] = 0x01; buffer[1] = 0x06; buffer[2] = 0x01; buffer[3] = 0x00; buffer[4] = 0x00; buffer[5] = 0x02; crc = GetCRCData(&buffer[0], 6); printf("%X\n",crc); getchar(); }
感谢有帮助的小伙伴转走。
、
、
、
、
、
持之以恒的学习是人类进步的阶梯