现在在研究SD卡,刚刚开始,却感觉困难重重,可能是比较笨吧,好不容易到了CMD8命令,发现用了几张卡,发送CMD8命令(0x48,0x00,0x00,0x01,0xAA,0x87)返回应答都是0x09,显示CRC校验错误,一开始以为是卡的问题,可是换了几张卡都这样,开始怀疑是不是校验0x87真的错了?
这是从网上的程序中得到的值,主要是自己不知道CRC7校验的生成过程,所以不确定就开始怀疑了,看到SD卡协议中有相关说明:
但是还是不明白具体过程,然后开始在网上找资料,关于这方面的资料很少,不过最后大概明白了它的计算过程,然后自己用QT写了个计算CRC7的程序,经过验证,上面CMD8命令的校验码就是0x87,
下面贴上计算校验码的相关部分程序:
//计算CRC7
//传进来的数组指针应该后面有余量,起码多出一个字节,用于存放CRC补上的7个0位
//计算方法是根据SD卡协议4.5节得出的
quint8 Widget::Crc7(quint8 *calByte,quint16 calNum) //计算CRC7
{
quint8 Crc_Num2=0x89; //CRC7的多项式
quint16 Crc_Num3=1; //计数数组中提供移位的字节的位置
quint16 Crc_Num4=0x80; //计数移位字节中该移哪一位
quint8 Crc_Num5=*calByte; //除法计算中的被除数,也存结果
//quint8 Crc_Num6=0; //存储除法计算中的余数,即异或后的值
*(calByte+calNum)=0; //讲数组扩充一个字节,并补0
while(1)
{
if((Crc_Num5&0x80)==0x80) //检查最高位是否为1
{
Crc_Num5=Crc_Num5^Crc_Num2;
}
else //最高位不为时,从后面字节借位,向前移一位
{
if((Crc_Num3==calNum)&&(Crc_Num4==0x01)) //移到最后一个字节倒第二位了
{
break; //退出循环
}
if(Crc_Num4==0x00) //当前字节移完,换下一个字节
{
Crc_Num4=0x80;
Crc_Num3++;
}
else
{
Crc_Num5<<=1; //左移1位
if(((*(calByte+Crc_Num3)&Crc_Num4)==0)) //补上1位
Crc_Num5&=0xFe;
else
Crc_Num5|=0x01;
Crc_Num4>>=1;
Crc_Num4&=0x7F;
}
}
}
return Crc_Num5;
}
现在好了,既然不是校验码的问题,那问题就麻烦了。。。。
继续研究吧。。。
|