转自:http://bbs.21ic.com/icview-111321-1-1.html
MCU之CRC计算
关于CRC算法
关于CRC算法,知其然,如果再知其所以然,事情就会清楚了。CRC算法,最重要的参数当然是生成多项式(CRC Polynomial),但(余数)初值和CRC数据最高位的位置也是很重要的两个参数,而这两个参数需要根据具体情况具体分析的。初值一般是全0或者全1,CRC数据最高位一般在最低字节的最低位或者最高位。CRC算法,作为一种检错算法,它的着眼点是出错概率高地方的错误,这在一定程度上决定了后两个参数。下面举例来说明。
1.串口通信在通信电缆的出错概率高,而串口数据是从LSb先发送,所以比较合理的做法是 CRC数据最高位是第1个被发送字节的最低位。如果发送的数据是"123"-0x31 0x32 0x33,那么输入的CRC数据是 1000 1100 0100 1100 1100 1100。另外,串口的缺省数据一般是1,那么比较合理的(余数)初值就是全1。
2.SPI(和I2C)通信在串行通信的出错概率高,而SPI数据(8位)一般是从MSb先发送,所以比较合理的做法是 CRC数据最高位是第1个被发送字节的最高位。如果发送的数据是"123"-0x31 0x32 0x33,那么输入的CRC数据是 0011 0001 0011 0010 0011 0011。另外,SPI的没有缺省数据,那么(余数)初值设置为全0或者全1都可以。
3.存储介质是FLASH(包括NAND、NOR、SPI FLASH),由于缺省数据(在擦除后)
是全1,比较合理的(余数)初值就是全1。
4.存储介质是硬盘,由于缺省数据(买来时)是全0,比较合理的(余数)初值就是全0。
问:SPI FLASH,比较合理的参数是什么?
答:如上所述,比较合理的(余数)初值是全1。
比较合理的做法是 CRC数据最高位是第1个字节的最高位;如果
SPI数据(8位)是从LSb先发送,比较合理的做法是 CRC数据最高位是第1个字节的最低位。
对于STM32的32位CRC,如果假定它的一个主要目的是为了校验往内部FLASH
存储数据的可靠性,那么(余数)初值是全1当然是比较合理的。
由于STM32的32位CRC是纯32位,即每次必须输入32位的数,所以如果数据不到
32位,应该往低位用1来填充比较合理;另外,如果输入数据是"1234"-0x31 0x32 0x33 0x34,那么输入的CRC数据是 0011 0100 0011 0011 0011 0010 0011 0001,由于STM32的32位CRC是纯32位且STM32是按小端对齐(little endian)的,这也是合理的。