wangqh1983 发表于 2013-11-19 19:11:48

CRC16 校验一串数据和把数据一个一个读出来校验结果不一样

我有一组备份数据是备份原数组的数据放到了EEPROM里,当出现运行故障时,可以把备份的数据恢复出来。但是恢复之前要检查EEPROM数据的有效性,写的时候我是将数组及数组尾部的CRC校验一同写入的。可是读EEPROM时我又不想开一个不常用的缓冲区,如何能实现从EEPROM中读出数据进行校验和数组进行校验的结果是一样的方法呢?

mhw 发表于 2013-11-19 20:33:05

给你个用了10多年的……这个是可以把一个长数组拆成N段甚至逐字节校验的:
u16 Calculate_CRC16(u16 CRC16,u8 *Buff,u16 Len)
{
        u8 da=0;
        u16 const crc_ta=        //CRC余式表
        {
                0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,
                0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,
        };
        while(Len--)
        {
                da = (u8)((CRC16 >> 12)&0x000f);        //暂存CRC的高四位
                CRC16 = (CRC16<<4)&0xffff;                        //CRC左移4位,相当于取CRC的低12位
                CRC16 ^= crc_ta;         //CRC的高4位和本字节的前半字节相加后查表计算CRC,然后加上上一次CRC的余数
                da = (u8)((CRC16 >> 12)&0x000f);        //暂存CRC的高四位
                CRC16 = (CRC16<<4)&0xffff;                        //CRC左移4位,相当于取CRC的低12位
                CRC16 ^= crc_ta;        //CRC的高4位和本字节的后半字节相加后查表计算CRC,然后再加上上一次CRC的余数
                Buff++;
        }
        return(CRC16);
}

mhw 发表于 2013-11-19 20:37:30

示例:
u8 const array[]={1,2,3,4,5,6,7,8,9,10};
u16 crc1 = Calculate_CRC16(0,array,sizeof(array));//单次校验。初值0
u16 crc2=0;//初值0
for(i=0;i<sizeof(array);i++)
{
crc2 = Calculate_CRC16(crc2 ,array+i,1);//逐字节校验。初值是上次的结果
}

wangqh1983 发表于 2013-11-20 09:25:58

mhw 发表于 2013-11-19 20:37 static/image/common/back.gif
示例:
u8 const array[]={1,2,3,4,5,6,7,8,9,10};
u16 crc1 = Calculate_CRC16(0,array,sizeof(array));// ...

非常感谢你,虽然你使用的多项式和我使用的不同,但是我已经知道这是个可行的办法;我会借鉴你的方法修改我的代码。谢谢!
页: [1]
查看完整版本: CRC16 校验一串数据和把数据一个一个读出来校验结果不一样