CRC16算法实现

来源:互联网 发布:knx网络专用线缆 编辑:程序博客网 时间:2024/05/16 11:38

  在这里不对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

}