||
在这里不对CRC的原理做过多的介绍,只介绍具体的算法实现。
CRC16的多项式码为X16+X15+X2+1,二进制表示为1 1000 0000 0000 0101,对应的十六进制为8005(因为CRC16是两个字节,所以最高位忽略掉了)。
具体计算方法为:
1、设置CRC寄存器,给其赋值0xffff;
2、将待校验数据的第一个字节(8bit)与16位CRC的低字节进行异或操作,结果存入CRC寄存器;
3、CRC寄存器向右移一位,MSB补零,移出并检查LSB;
4、如果LSB为0,重复第三步;若LSB为1,CRC寄存器与多项式码(8005)相异或,结果依然存入CRC寄存器;
5、重复第3、4步,直到8次移位全部完成。即一个8bit字节处理完毕;
6、重复第2至第5步,即依次处理后面的数据字节,直到全部数据处理完成;
7、最终CRC寄存器里的内容即为CRC值。
在数据传输中,附加在有效信息后面的CRC16两个字节,高字节在前,低字节在后。
CRC16的c语言实现代码:
/*输入m:待校验的数据,加CRC字节
输入len:待校验数据的长度,不包括CRC
校验结果附加在原数据的最后
输出:1 校验正确
0 校验错误
*/
unsigned char crc (unsigned char *m, unsigned int len)
{
unsignedchar RCR2,RCR3;
unsigned chargk,gj,gi,f_temp,f_hz;
gk=0xff; //CRC16低字节
gj=0xff; //CRC16高字节
RCR2=*(m+len); //接收到的数据的crc高字节
RCR3=*(m+len+1); //接收到的数据的crc低字节
*(m+len)=0;
*(m+len+1)=0;
len++;
while(len!=0)
{
gk^=*m;
*m++;
for(gi=0;gi<8;gi++)
{
if ( (gj& 0x01) == 0) f_hz=0; else f_hz=1;
gj>>=1;
if ( (gk & 0x01) == 0)f_temp=0; else f_temp=1;
gk>>=1;
if(f_hz==1) //gj的LSB=1
gK|=0X80; //把gJ的lSB移入gK的最高位
if(f_temp==1) //gk的LSB=1
{
gk^=0x05;
gj^=0x80;
}
}
len--;
}
*(m-1)=gj;
*m=gk;
if(gk==RCR3&& gj==RCR2)
return 1; //校验正确返回1
else
return 0; //校验错误返回0
}