c. CRC通用计算程序

由于STM32的硬件CRC计算不能满足SD卡及其标准所规定的CRC数据,本文讨论软件实现通用的CRC计算,以及SD使用到的CRC7和CRC16的数据。

这里的程序并非最简化的程序,实用化之前可以进行优化。

CRC的计算有两个输入量,被校验数据,和多项式

严格的来讲,CRC是按位计算的bit,而以字节为输入是比较通用和符合效率的,如果以多项式的长度作为输入会增加算法的难度

unsigned int crc_common(unsigned char* dat, unsigned int cnt, unsigned int plnm, unsigned int dgt)

unsigned int crc_common(unsigned char* dat, unsigned int cnt, unsigned int plnm, unsigned int dgt)

计算每一字节并与以前的结果叠加

while (cc < cnt) {

cbr = crc_byte((cbr<<8)|dat[cc], plnm, dgt);

cc++;

}

在最后需要补足与多项式长度相同的0,长度大于8位,一个字节时重复字节计算

while (cc > 8) {

cbr = crc_byte(cbr<<8, plnm, dgt);

cc -= 8;

}

cbr = crc_byte(cbr<<cc, plnm, dgt);

crc_byte 计算每个附加字节的crc结果

mxw = (0x1 << dgt) - 1;

while ((cwd & crcc)==0) {

crcc >>= 1;

crcp >>= 1;

}

cwd ^= crcp;

crc7和crc16的定义

这里使用的多项式加入了最高位以方便计算

#define crc7pm 0x89

#define crc16pm 0x11021

unsigned char crc7(unsigned char* dat, unsigned int cnt) {

return crc_common(dat, cnt, crc7pm, 7);

}

unsigned int crc16(unsigned char* dat, unsigned int cnt) {

return crc_common(dat, cnt, crc16pm, 16);

}