首先看一个CRC8的校验程序,是DS18B20使用的G(x)=x^8+x^5+x^4+1;
uint8_t CRC8( uint8_t *P,uint8_t Len )
{
uint8_t num,Data;
uint8_t CRC_Reg=0;
while(Len--)
{
Data = *P;
for (num=0;num<8;num++)
{
if ((Data^CRC_Reg)&0X01 != 0) // DS18B20数据的最低位开始移入移位寄存器
{ // 若数据的最低位与移位寄存器的最低位异或结果为1
//CRC_Reg ^= 0X18; // 第四五位与1做或运算并且存入移位寄存器
//CRC_Reg >>= 1; // 移位寄存器数据右移一位
//CRC_Reg |= 0X80; // 运算结果1存入数据移位寄存器最后一位
CRC_Reg >>= 1;
CRC_Reg ^= 0X8C;
}
else
{ // 若数据的最低位与移位寄存器的最低位异或结果为0
// 第四五位与0做异或运算并且存入移位寄存器,0做异或运算为原数值
CRC_Reg >>= 1; // 移位寄存器数据右移一位,与此同时也完成了末位添加0的运算
}
Data >>= 1;
}
P++;
}
return CRC_Reg;
}
上一个测试了一下没什么问题,
又编写了CRC16CCIT的G(x)=x^16+x^12+x^5+1;
uint16_t CRC_CCIT_16( uint8_t *P,uint16_t Len ) //指针指向的数据顺序影响校验结果,
{ //此计算过程先计算指针指向的最低字节
uint16_t CRC_Reg;
uint8_t num;
uint8_t Data;
CRC_Reg = 0;
while(Len--) //剩余需要校验的字节数
{
Data = *P;
for (num=0;num<8;num++) //每一个校验字节要移动8次
{
if ((Data^CRC_Reg)&0X0001 != 0) //校验数据从LSB开始
{
CRC_Reg >>= 1; //判断完成后将最低位移除
CRC_Reg = CRC_Reg^0X8408;
/*CRC_Reg |= 0X8000;*/ //0X8408可将最高位设置为1
}
else
{
CRC_Reg >>= 1;
}
Data >>= 1;
}
P++;
}
return CRC_Reg;
}
但是这个程序就有问题,我一直没照找到哪里有问题!
下面给一个网络上找的自己稍微修改了一下,没什么问题,
uint16_t CRC16( uint8_t *P,uint16_t Len )
{
uint16_t CRC=0;
uint8_t Data,i;
while(Len--)
{
Data = *P;
for(i=0x01;i!=0;i<<=1)
{
if ((CRC&0X8000)!=0)
{
CRC <<= 1;
CRC ^= 0X1021;
}
else
{
CRC <<= 1;
}
if((Data&i)!=0)
CRC ^= 0X1021;
}
P++;
}
return CRC;
}
问题来了,我的第二个程序自己是将第三个正确程序的CRC_Reg(移位寄存器)左右颠倒使用,再就是将数据移入位和从寄存器移出的那一位的异或结果一次性判断来完成。
不知道表述清楚没,希望有心的人给看看不胜感激!就当自己复习了,我比较愚钝看了三天还是无解······
|