在這裏不對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
}