您的位置:首页 > 其它

SD卡驱动

2016-05-22 23:27 204 查看
SD在平时日常生活中的使用非常广泛,平时的消费类电子产品也都有配置SD卡,最近在搞STM8L的SPI模块,就想着也把这个SD卡也做进去。

SD卡

SD卡简介

SD卡定义:

SD卡是基于flash的存储卡。

SD卡和MMC卡的区别在于初始化过程不同。

SD卡的通信协议包括SD总线和SPI两类。

SD卡使用卡内智能控制模块进行FLASH操作控制,包括协议、安全算法、数据存取、ECC算法、缺陷处理和分析、电源管理、时钟管理。

通信电压范围:2.0-3.6V;工作电压范围:2.0-3.6V

最大读写速率:10Mbyte/s

最大10 个堆叠的卡(20MHz,Vcc=2.7-3.6V)

SD卡类型:

MMC卡: MultiMedia card,有 7 个触点( 引脚),分为两种操作模式,分别为 MMC模式与SPI 模式,两种模式对引脚的定义是不同的。SPI 模式只有 Host 具有SPI 接口时才能使用。MMC只具有存储功能,不像SD卡还具有加密功能。

SD卡: Security Digtial card,共有9 个触点( 引脚),多余的 2 个引脚为数据线,但使用与 MMC卡兼容的模式时,这两个多余的引脚没有起到作用。SD卡除了存储功能外,还有一种加密功能,但加密功能是收费的(所以开源的linux中只包含mmc的驱动目录),因为当初SD卡联盟中(索尼)就是发明这种卡就是用来存储音乐(淘汰卡带),并使用加密特性,防止拷贝。

TF卡:软件上SD卡一致,只是在硬件的体积上比SD卡西小,所以市场上很多的TF卡的SD外形卡套

SDIO卡: 这种卡并不是存储卡,可以理解为一个SDIO接口卡,如WIFI(SDIO接口);并非memory卡,故名思意,就是输入/ 输出卡,这种卡有用于 LAN的、也有用于蓝牙的。

SD管脚:

SD卡管脚:



Micro SD卡(TF卡):



SD卡版本:

SD V1.X(即SD标准卡)最大容量2GB

SD V2.0 2.0版本的标准卡,最多2GB

SD V2.0HC 2.0高容量卡,最多32GB

SD卡中的SPI模式

指令格式

在SPI模式下,数据都是以字节(Byte)为单位进行传输的。此时SD卡作为从机设备,一般的操作是MCU发送带有参数的命令,SD卡接收到命令和参数后进行操作,并且返回响应,MCU根据返回的响应进行下一步操作。

每条指令都是6个字节(48位),指令的开始位是第一个字节的最高位,以它为开始传输指令,第45-40字节:指令的序号,例如CMD0 代表0x00CMD8代表0x08;整个指令格式如下:



至于SD卡支持的指令可以具体看看数据手册是列表。

还要说一下ACMD指令,ACMD指令是特殊指令,MCU要发送该类指令时需要先发送CMD55的指令,告诉SD卡控制器后面的指令时ACMD指令。

指令返回

不同的指令有不同的指令返回,有R1、R2等,具体介绍R1、R3和R7,其他的要详细看手册。

R1是一个1字节长的的响应,最高位始终为0,其余各位为状态位(如下图所示)。



R3响应的格式是R1+OCR寄存器,OCR是一个32位的寄存器,存放的是SD卡的操作电压范围,具体见下图:



R7响应也是由R1+32位长的数据组成,具体见下图:



重点说说CMD8这个指令,这个指令用来区分SD卡所支持的版本即上面所说的SDV1.0 V2.0,以及检测SD卡接口电压是否满足要求,该指令的返回时 R7 类型。



一般发送CMD8的指令为:0x48 0x00 0x00 0x01 0xAA 0x87,其中VHS 该位置1,pattern为0xAA,CRC 为0x87,如果该卡支持CMD8,会返回上图的结果:0x01 0x00 0x00 0x01 0xAA, 如果不支持该指令,那么返回中R1的值就不是0x01。

SD卡初始化

有了这些基本知识,下面就讨论下SD卡在SPI模式下的初始化激活过程。

SD卡初始化激活

在手册中,激活过程如下图:



第一步,上电,将CS信号拉低,给SD卡发送至少74个时钟周期(发送10个0xFF),让SD卡完成自身检查和初始化,进入空闲状态(IDLE)。之后,对SD卡发送CMD0使其进入SPI模式。不论你是什么卡,SD卡从D_OUT线上的返回值都是一样的,如果是0x01,说明CMD0操作是成功的,此时SD卡还处在IDLE状态。

第二步,发送CMD8命令,上面说过,可以通过CMD8的返回来确定SD卡的版本,如果SD卡对此命令不识别,那么说明你的SD卡的版本是旧的,如果SD卡对CMD8有正确的返回值,那么你的SD卡的硬件层版本是2.0的,支持大容量储存的,属于SDHC卡。

第三步,如果CMD8指令有正确的返回,那么就可以用ACMD41命令将SD卡从IDLE状态切换到读写状态,要发送ACMD41 命令,需要先发送CMD55 命令,如果SD卡能正常切换状态进入读写状态,那么返回的R1类型的值为0x00,如果出现其他值,那么表明切换失败。

SD卡读写

未完待续

PS:在STM8L151G6平台上,对SPI的配置会影响通信的数据正确性,如下面的SPI配置(有外接上拉电阻):

/*PB5:SPI_CLK*/
GPIO_Init(GPIOB, GPIO_Pin_5, GPIO_Mode_Out_OD_Low_Slow);
/*PB6:SPI_MOSI*/
GPIO_Init(GPIOB, GPIO_Pin_6, GPIO_Mode_Out_OD_Low_Slow);
//主机模式,配置为输入
GPIO_Init(GPIOB, GPIO_Pin_7, GPIO_Mode_In_FL_No_IT);
/* SD_SPI Config */
SPI_Init(SPI1, SPI_FirstBit_MSB, SPI_BaudRatePrescaler_128, SPI_Mode_Master,
SPI_CPOL_High, SPI_CPHA_2Edge, SPI_Direction_2Lines_FullDuplex,
SPI_NSS_Soft, 0x07);
/* SD_SPI enable */
SPI_Cmd(SPI1, ENABLE);
SD_WriteReadByte(0xFF);


上面的这种配置会导致通信失败,具体体现在CMD8(0x48 0x00 0x00 0x01 0xAA 0x87)的返回上,正确的返回时应是0x01 0x00 0x00 0x01 0xAA,但是在这种配置下返回的是0x01 0x00 0x00 0x01 0xAB,在后面不对了。但是只要把SPI的配置改成下面这种就好了。

/*PB5:SPI_CLK*/
GPIO_Init(GPIOB, GPIO_Pin_5, GPIO_Mode_Out_PP_High_Fast);
/*PB6:SPI_MOSI*/
GPIO_Init(GPIOB, GPIO_Pin_6, GPIO_Mode_Out_PP_High_Fast);
//主机模式,配置为输入
GPIO_Init(GPIOB, GPIO_Pin_7, GPIO_Mode_In_FL_No_IT);
/* SD_SPI Config */
SPI_Init(SPI1, SPI_FirstBit_MSB, SPI_BaudRatePrescaler_128, SPI_Mode_Master,
SPI_CPOL_High, SPI_CPHA_2Edge, SPI_Direction_2Lines_FullDuplex,
SPI_NSS_Soft, 0x07);
/* SD_SPI enable */
SPI_Cmd(SPI1, ENABLE);
SD_WriteReadByte(0xFF);


目前还没有找到这个问题的原因。

参考资料:

* http://www.tuicool.com/articles/aimqQ3

* http://blog.sina.com.cn/s/blog_4f09c0b50101636h.html

* /article/11545140.html

* /article/8116417.html

* http://elm-chan.org/docs/mmc/mmc_e.html

* http://comm.chinaaet.com/adi/blogdetail/38988.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: