V2.0版SD卡在SPI模式下使用CMD8的操作
使用STM32学习板操作SD卡时,遇到了初始化中检测SD卡类型的问题,查看学习板带的源程序发现使用了CMD8命令进行判断SD卡的类型,在网上查了好久查不到有关SDV2.0中CMD8命令的详细描述,于是自己看了英文版的SDV2.0协议(2006),找出了CMD8命令的章节,翻译了一下,然后加上一些自己的理解,构成了这篇说明。
首先简单说一下SD卡的初始化过程,这个过程很多文章都有叙述,此处简单摘自其他文章如下:
(1).首先延时74CLK,然后发送CMD0命令,得到返回值0X01;
(2).然后进入卡类型检验。为了检验卡的类型,首先发送只有V2.0版的SD卡才具有的命令CMD8,然后检测返回值:
返回值若是0X01,则表示此卡为V2.0卡,然后再发送循环命令CMD55+ACMD41,直到返回0x00,确定SD2.0卡初始化成功;然后再发送CMD58命令,接收返回的OCR 寄存器的数据,其中第31位用于判断V2.0的卡是否为SDHC类型。
若返回值不为0X01,则进一步判断是V1.0卡还是MMC卡:先发送循环命令
CMD55+ACMD41进行复位,如果复位不成功则考虑是MMC卡,如果复位成功,则为V1.0卡。在复位不成功的情况下,再使用CMD1进行复位,如果复位成功,则表明是MMC卡,如果复位不成功,则表示是无法识别的卡。
从上面的初始化过程可以看出主要涉及到4个特殊的命令:CMD8、CMD55、CMD41、CMD58。对于CMD55和CMD41的讲解,有很多文章都有,不多解释,此复位命令的返回值和CMD1的返回值相同,成功复位时返回0X00;对于CMD58,其命令码格式是标准格式,其中数据填充0即可,CRC也可省略,只要最后加上停止位‘1’即可,不作详解;其返回值为R3类型,首先接收到一个字节应该为0X00,表示SD卡响应命令成功,然后接收4字节的OCR寄存器值;OCR寄存器的第30位(CCS)指示了卡的类型是否为
SDHC,此位为1则为SDHC,为0则为SDSC;
重点讲一下CMD8命令:
(1).发送的命令格式如下:
其中需要注意的是VHS。如果单片机支持2.7-3.6v的SD卡,那么这个半字节应该写成‘0001’。STM32单片机用的是3.3V电压,当然支持,如果不支持还怎么做实验。
然后注意CHECK PATTERN这个字节,这个字节的特点是,你在这个发送的命令中写的是什么,那么接收CMD8命令的回复时接收到的就是什么,比如如果这个字节写成“0XAA”,那么当接收CMD8命令回复的数据时接收到的也是“0XAA”;
发送的CMD8命令数据可以如下:
[0X48(CMD8)、0X00、0X00、0X01、0XAA、0X87];
(2).接收SD卡响应CMD8命令后返回的数据格式:
在SDV2.0协议中,CMD8的返回值格式为R7,如下所示:
首先可以接收到第一个字节格式为R1的数据,这个数据只要判断是否为0X01即可,如果为0X01,表示SD卡响应了CMD8命令,如果不为0X01(一般会是0X09或0X05,不用关心),则表示SD卡不支持CMD8命令。
在接收到0X01之后,随后需要接收4字节数据,其中31-28位为command version,即命令的类型,此处为CMD8;然后27-12位是保留的数据位,通常为0;然后11-8位是SD卡支持的电压范围,此处得到的应该是‘0001’;最后一个字节是我们在CMD8的命令中发送给SD卡的数据,SD卡又原模原样的返回来了,在命令中我们发送的是0XAA,此处得到的也应该是0XAA。
最后,这样解释下来,对于一般的应用应该可以满足了,至于更多的信息,请读者参阅SD卡V2.0的英文版协议(2006)吧。以上仅仅是个人对SD卡V2.0协议中有关CMD8命令的一些理解,如有错误之处希望读者能给予指正,技术重在交流。
作者:嵌入式奋勇前进
2013-10-1 [email protected]