LV16-21-SDIO-01-SD卡基础知识
本文主要是SD卡的一些基础知识相关笔记,若笔记中有错误或者不合适的地方,欢迎批评指正😃。
点击查看使用工具及版本
Windows | windows11 |
Ubuntu | Ubuntu16.04的64位版本 |
VMware® Workstation 16 Pro | 16.2.3 build-19376536 |
SecureCRT | Version 8.7.2 (x64 build 2214) - 正式版-2020年5月14日 |
开发板 | 正点原子 i.MX6ULL Linux阿尔法开发板 |
uboot | NXP官方提供的uboot,NXP提供的版本为uboot-imx-rel_imx_4.1.15_2.1.0_ga(使用的uboot版本为U-Boot 2016.03) |
linux内核 | linux-4.15(NXP官方提供) |
STM32开发板 | 正点原子战舰V3(STM32F103ZET6) |
点击查看本文参考资料
- 通用
分类 | 网址 | 说明 |
官方网站 | https://www.arm.com/ | ARM官方网站,在这里我们可以找到Cotex-Mx以及ARMVx的一些文档 |
https://www.st.com/content/st_com/zh.html | ST官方网站,在这里我们可以找到STM32的相关文档 | |
https://www.stmcu.com.cn/ | 意法半导体ST中文官方网站,在这里我们可以找到STM32的相关中文参考文档 | |
http://elm-chan.org/fsw/ff/00index_e.html | FatFs文件系统官网 | |
教程书籍 | 《ARM Cortex-M3权威指南》 | ARM公司专家Joseph Yiu(姚文祥)的力作,中文翻译是NXP的宋岩 |
《ARM Cortex-M0权威指南》 | ||
《ARM Cortex-M3与Cortex-M4权威指南》 | ||
开发论坛 | http://47.111.11.73/forum.php | 开源电子网,正点原子的资料下载及问题讨论论坛 |
https://www.firebbs.cn/forum.php | 国内Kinetis开发板-野火/秉火(刘火良)主持的论坛,现也做STM32和i.MX RT | |
https://www.amobbs.com/index.php | 阿莫(莫进明)主持的论坛,号称国内最早最火的电子论坛,以交流Atmel AVR系列单片机起家,现已拓展到嵌入式全平台,其STM32系列帖子有70W+。 | |
http://download.100ask.net/index.html | 韦东山嵌入式资料中心,有些STM32和linux的相关资料也可以来这里找。 | |
博客参考 | http://www.openedv.com/ | 开源网-原子哥个人博客 |
http://blog.chinaaet.com/jihceng0622 | 博主是原Freescale现NXP的现场应用工程师 | |
cortex-m-resources | 这其实并不算是一个博客,这是ARM公司专家Joseph Yiu收集整理的所有对开发者有用的官方Cortex-M资料链接(也包含极少数外部资源链接) |
- STM32
STM32 | STM32 HAL库开发实战指南——基于F103系列开发板 | 野火STM32开发教程在线文档 |
STM32库开发实战指南——基于野火霸道开发板 | 野火STM32开发教程在线文档 |
- SD卡
SD Association | 提供了SD存储卡和SDIO卡系统规范 |
点击查看相关文件下载
STM32F103xx英文数据手册 | STM32F103xC/D/E系列的英文数据手册 |
STM32F103xx中文数据手册 | STM32F103xC/D/E系列的中文数据手册 |
STM32F10xxx英文参考手册(RM0008) | STM32F10xxx系列的英文参考手册 |
STM32F10xxx中文参考手册(RM0008) | STM32F10xxx系列的中文参考手册 |
Arm Cortex-M3 处理器技术参考手册-英文版 | Cortex-M3技术参考手册-英文版 |
STM32F10xxx Cortex-M3编程手册-英文版(PM0056) | STM32F10xxx/20xxx/21xxx/L1xxxx系列Cortex-M3编程手册-英文版 |
SD卡相关资料——最新版本 | 有关SD卡的一些资料可以从这里下载 |
SD卡相关资料——历史版本 | 有关SD卡的一些历史版本资料可以从这里下载,比如后边看的SD卡2.0协议 |
SD 2.0 协议标准完整版 | 这是一篇关于SD卡2.0协议的中文文档,还是比较有参考价值的,可以一看 |
这篇笔记主要看的是文档 Physical Layer Simplified Specification v9.0 ,但其实应该看文档Physical Layer Simplified Specification v2.0可能会更好一些,虽然他们基本是一样的(因为后边好像说是STM32做多支持到2.0版本的SD卡)。
一、SD卡简介
1. 什么是SD卡?
SD卡(Secure Digital Memory Card)即:安全数码卡,它是在MMC的基础上发展而来,是一种基于半导体快闪记忆器的新一代记忆设备,是SD协会开发的一种专有 的非易失性 存储卡格式,用于便携式设备。由于它体积小、数据传输速度快、可热插拔等优良的特性,被广泛地于便携式装置上使用,例如数码相机、个人数码助理(PDA)和多媒体播放器等。
SD卡由日本松下、东芝及美国SanDisk公司于1999年8月共同开发研制。作为对MultiMediaCard(MMC)的改进,现已成为行业标准。这三家公司组成了SD-3C,LLC,这家公司许可并执行与SD存储卡以及SD主机和辅助产品相关的知识产权。两家公司还于2000年1月成立了非营利组织SD协会(SDA),以促进和创建SD卡标准。SDA如今有大约1,000个成员公司。SDA使用SD-3C拥有并许可的多个商标徽标,以强制遵守其规范并确保用户的兼容性。
2. 长啥样?
这样的话,我们就去某宝看一看吧:
我们搜索关键词,就会出现下边这些类型的,我们会发现,似乎有两种形状,一种比较大,一种比较小,但是简介好像都叫SD卡。那就来了解一下吧。
2.1 TF卡
Micro SD Card,原名Trans-flashCard(TF卡),2004年正式更名为MicroSD Card,由SanDisk(闪迪)公司发明。MicroSD卡是一种极细小的快闪存储器卡,其格式源自SanDisk创造,原本这种记忆卡称为T-Flash,及后改称为TransFlash;而重新命名为MicroSD的原因是因为被SD协会(SDA) 采立。
它的体积为15mm x 11mm x1mm,差不多相等于手指甲的大小,是现时最细小的记忆卡。它也能通过SD转接卡来接驳于SD卡插槽中使用。现时MicroSD卡提供128MB、256MB、512MB、1G、2G、4G、8G、16G、32G、64G、128G的容量(MWC2014 世界移动通信大会期间,SanDisk(闪迪)打破了储存卡最高64GB容量的传统,正式发布了一款容量高达128GB的Micro SD XC 储存卡。
2.2 SD卡
SD卡(Secure Digital Memory Card)即:安全数码卡,就前边介绍的那样,俗称大卡,是一种发展时间比较久的内存卡,SD卡的标准尺寸为24mm×32mm×2.1mm。
2.3 TF卡转SD卡?
MicroSD的体积更小且可以转换SD卡使用,TF卡的电路和引脚和SD卡是一样的。TF卡可经SD卡转换器后,当SD卡使用,SD卡在一般情况下无法转换成TF卡,毕竟大小在哪摆着。
3. 官方宣传册?
这一部人可以查看官方网站的宣传册:SDA_brochure_EN.pdf,这个具体的还是看在线文档吧,简单了解一下,对后边自己购买SD卡也有帮助,比如SD卡上边标注的 class等参数是什么意思?
4. SD卡分类
SD卡按容量分类,可以分为3类:SD卡、SDHC卡、SDXC卡,如下表所示:
容量 | 命名 | 简称 |
---|---|---|
0~2G | Standard Capacity SD Memory Card | SDSC或SD |
2G~32G | High Capacity SD Memory Card | SDHC |
32G~2T | Extended Capacity SD Memory Card | SDXC |
这个其实在文档 Physical Layer Simplified Specification v9.0 的 2. System Features一节中的Capacity of Memory部分有说明。
二、SD卡物理结构
1. 包含哪些?
这张图我们可以查看 文档 Physical Layer Simplified Specification v9.0 的 3.7 SD Memory Card-Pins and Registers一节。
一张SD卡包括有存储单元、存储单元接口、电源检测、卡及接口控制器和接口驱动器5个部分 :
(1)存储单元是存储数据部件,存储单元通过存储单元接口与卡控制单元进行数据传输,这一部分属于NAND FLASH;
(2)电源检测单元保证SD卡工作在合适的电压下,如出现掉电或上状态时,它会使控制单元和存储单元接口复位;
(3)卡及接口控制单元控制SD卡的运行状态,它包括有8个寄存器用于设定或表示SD卡信息。这些寄存器只能通过对应的命令访问, 一共定义有64个命令,每个命令都有特殊意义,可以实现某一特定功能, SD卡接收到命令后,根据命令要求对SD卡内部寄存器进行修改,程序控制中只需要发送组合命令就可以实现SD卡的控制以及读写操作。
(4)接口驱动器控制SD卡引脚的输入输出 。
2. 寄存器简介
名称 | bit宽度 | 描述 |
---|---|---|
CID | 128 | 卡识别号(Card identification number):用来识别的卡的个体号码(唯一的) |
RCA | 16 | 相对地址(Relative card address):卡的本地系统地址,初始化时,动态地由卡建议,主机核准。 |
DSR | 16 | 驱动级寄存器(Driver Stage Register):配置卡的输出驱动 |
CSD | 128 | 卡的特定数据(Card Specific Data):卡的操作条件信息 |
SCR | 64 | SD配置寄存器(SD Configuration Register):SD 卡特殊特性信息 |
OCR | 32 | 操作条件寄存器(Operation conditions register) |
SSR | 512 | SD状态(SD Status):SD卡专有特征的信息 |
CSR | 32 | 卡状态(Card Status):卡状态信息 |
每个寄存器的含义我们可以参考 文档 Physical Layer Simplified Specification v9.0 的 5.Card Registers,里边有对每个寄存器的详细描述。这里选几个重要的,我们可能会用到的说明一下。
(1)CID :就是一个卡识别号,每一张卡的号都是唯一的,厂家生产SD卡的时候,需要向SD卡的那个标准组织购买卡号的,所以每一张的卡识别号都应该是唯一的。包括有提供制造商ID、OEM/应用ID、产品名称、版本、序列号、制造日期等信息。
(2)CID :相对地址,这个主要是因为CID太长了,有128位,每一次通讯都通过这么长的CID号来查找是要跟哪一张SD卡通信的话,就比较麻烦了,所以出现了相对地址,那什么是相对地址呢?比如我们在STM32上边接了两张SD卡,这样我们就可以将第一张相对地址指定为0,第二张指定为1,这样就很好区分啦。可动态变化,在主机初始化的时候确定。(仅SDIO模式下有,SPI模式下无RCA)
(3)SSR:包含了这一张SD卡的一些专有特征信息,比如读写的基本单位,块的大小这些信息。
(4)CSR:卡状态寄存器,我们可以从这里获取SD卡的擦除状态啊,写入状态啊,是否需要等待啊这些状态。
三、SD卡总线及协议
1. SDIO接口?
SD卡一般都支持SDIO和SPI这两种接口,支持SPI和SDIO两种模式:不同模式下,SD卡引脚功能描述如下表所示:
需要注意的是TF卡+卡套,组合起来也可以当SD卡用,不过,很大一部分TF卡,不支持SPI访问模式。所以,SPI驱动SD卡的时候,尽量选择大卡(SD卡),而不要选择TF卡。在这里我们只学习SDIO接口操作方式, SD卡与SDIO接口示意图如下
SD卡使用9-pin接口通信,其中3根电源线、 1根时钟线、 1根命令线和4根数据线,具体如下:
信号线 | 说明 |
---|---|
CLK | 时钟线,由SDIO主机产生,即由STM32控制器输出; |
CMD | 命令控制线, SDIO主机通过该线发送命令控制SD卡,如果命令要求SD,卡提供应答, SD卡也是通过该线传输应答信息; |
D0-3 | 数据线,传输读写数据; SD卡可将D0拉低表示忙状态; |
VDD、 VSS1、 VSS2 | 电源和地信号 |
SDIO的通信时序的物理逻辑非常简单, SDIO不管是从主机控制器向SD卡传输,还是SD卡向主机控制器传输都只以CLK时钟线的上升沿为有效。SD卡操作过程会使用两种不同频率的时钟同步数据,一个是识别卡阶段时钟频率FOD,最高为400kHz; 另外一个是数据传输模式下时钟频率FPP,默认最高为25MHz,如果通过相关寄存器配置使SDIO工作在高速模式,此时数据传输模式最高频率为50MHz。
2. 总线协议
关于总线协议,我们可以参考文档 Physical Layer Simplified Specification v9.0 的 3.6 Bus Protocol章节。
2.1 命令与响应
SD总线通信是基于命令和数据传输的。通讯由一个起始位(“0” ),由一个停止位(“1” )终止。 SD通信一般是主机发送一个命令(Command),从设备在接收到命令后作出响应(Response),如有需要会有数据(Data)传输参与。
命令与响应交互的过程如下图:
2.2 带数据块的通信
SD数据是以块(Black)形式传输的, SDHC卡数据块长度一般为512字节,数据可以从主机到卡,也可以是从卡到主机。数据块需要CRC位来保证数据传输成功。 CRC位由SD卡系统硬件生成。 STM32控制器可以控制使用单线或4线传输。
2.3 单块和多块的通信
SD数据传输支持单块和多块读写,它们分别对应不同的操作命令,多块写入还需要使用命令来停止整个写入操作。数据写入前需要检测SD卡忙状态,因为SD卡在接收到数据后编程到存储区过程需要一定操作时间。 SD卡忙状态通过把D0线拉低表示。 数据块读操作与之类似,只是无需忙状态检测。
2.4 数据位什么传输?
使用4数据线传输时,每次传输4bit数据,每根数据线都必须有起始位、终止位以及CRC位, CRC位每根数据线都要分别检查,并把检查结果汇总然后在数据传输完后通过D0线反馈给主机。
SD卡数据包有两种格式,一种是常规数据(8bit宽),它先发低字节再发高字节,而每个字节则是先发高位再发低位, 4线传输示意如下图:
另外一种数据包发送格式是宽位数据包格式,对SD卡而言宽位数据包发送方式是针对SD卡SSR(SD状态)寄存器内容发送的, SSR寄存器总共有512bit,在主机发出ACMD13命令后SD卡将SSR寄存器内容通过DAT线发送给主机。宽位数据包格式示意图如下:
四、SD卡命令
SD命令由主机发出,以广播命令和寻址命令为例,广播命令是针对与SD主机总线连接的所有从设备发送的,寻址命令是指定某个地址设备进行命令传输。这一章的内容我们可以参考文档 Physical Layer Simplified Specification v9.0 的 4.7 Commands 章节。
1. 命令格式
SD命令格式固定为48bit,都是通过CMD线连续传输的, 数据线不参与。
SD命令的组成如下:
(1)起始位和终止位:命令的主体包含在起始位与终止位之间,它们都只包含一个数据位,起始位为0,终止位为1。
(2)传输标志:用于区分传输方向,该位为1时表示命令,方向为主机传输到SD卡,该位为0时表示响应,方向为SD卡传输到主机。
(3)命令主体内容: 命令主体内容包括命令、地址信息/参数和CRC校验三个部分。
命令主体内容的三个部分说明如下:
命令号:它固定占用6bit,所以总共有64个命令(代号:CMD0~CMD63),每个命令都有特定的用途,部分命令不适用于SD卡操作,只是专门用于MMC卡或者SD I/O卡。
地址/参数:每个命令有32bit地址信息/参数用于命令附加内容,例如,广播命令没有地址信息,这32bit用于指定参数,而寻址命令这32bit用于指定目标SD卡的地址。
CRC7校验:长度为7bit的校验位用于验证命令传输内容正确性,如果发生外部干扰导致传输数据个别位状态改变将导致校准失败,也意味着命令传输失败, SD卡不执行命令。
2. 命令类型
SD命令有4种类型:
(1)无响应广播命令(bc),发送到所有卡,不返回任务响应;
(2)带响应广播命令(bcr),发送到所有卡,同时接收来自所有卡响应;
(3)寻址命令(ac),发送到选定卡, DAT线无数据传输;
(4)寻址数据传输命令(adtc),发送到选定卡, DAT线有数据传输。
另外, SD卡主机模块系统旨在为各种应用程序类型提供一个标准接口。在此环境中,需要有特定的客户/应用程序功能。为实现这些功能,在标准中定义了两种类型的通用命令: **特定应用命令(ACMD)和常规命令(GEN_CMD)**。 要使用SD卡制造商特定的ACMD命令如ACMD6,需要在发送该命令之前无发送CMD55命令,告知SD卡接下来的命令为特定应用命令。 CMD55命令只对紧接的第一个命令有效,SD卡如果检测到CMD55之后的第一条命令为ACMD则执行其特定应用功能,如果检测发现不是ACMD命令,则执行标准命令。
3. 命令描述
接下来我们来学习一下SD卡部分命令信息,更多详细信息可以参考SD简易规格文件说明,表中填充位和保留位都必须被设置为0。这一部分详细可以参考文档 Physical Layer Simplified Specification v9.0 的 4.7.4 Detailed command Description 一节。注意后边列举命令的时候是将保留的命令给去掉了。
3.1 基本命令(Class 0)
命令序号 | 类型 | 参数 | 响应 | 缩写 | 描述 |
---|---|---|---|---|---|
CMD0 | bc | [31:0]填充位 | - | GO_IDLE_STATE | 复位所有的卡到idle状态。 |
CMD2 | bcr | [31:0]填充位 | R2 | ALL_SEND_CID | 通知所有卡通过CMD线返回CID值。 |
CMD3 | bcr | [31:0]填充位 | R6 | SEND_RELATIVE_ADDR | 通知所有卡发布新RCA。 |
CMD4 | bc | [31:16]DSR[15:0]填充位 | - | SET_DSR | 编程所有卡的DSR。 |
CMD7 | ac | [31:16]RCA[15:0]填充位 | R1b | SELECT/DESELECT_CARD | 选择/取消选择RCA地址卡。 |
CMD8 | bcr | [31:12]保留位[11:8]VHS[7:0]检查模式 | R7 | SEND_IF_COND | 发送SD卡接口条件, 包含主机支持的电压信息, 并询问卡是否支持。 |
CMD9 | ac | [31:16]RCA[15:0]填充位 | R2 | SEND_CSD | 选定卡通过CMD线发送CSD内容 |
CMD10 | ac | [31:16]RCA[15:0]填充位 | R2 | SEND_CID | 选定卡通过CMD线发送CID内容 |
CMD12 | ac | [31:0]填充位 | R1b | STOP_TRANSMISSION | 强制卡停止传输 |
CMD13 | ac | [31:16]RCA[15:0]填充位 | R1 | SEND_STATUS | 选定卡通过CMD线发送它状态寄存器 |
CMD15 | ac | [31:16]RCA[15:0]填充位 | - | GO_INACTIVE_STATE | 使选定卡进入“inactive” 状态 |
3.2 面向块的读操作(Class 2)
命令序号 | 类型 | 参数 | 响应 | 缩写 | 描述 |
---|---|---|---|---|---|
CMD16 | ac | [31:0]块长度 | R1 | SET_BLOCK_LEN | 对于标准SD卡, 设置块命令的长度, 对于SDHC卡块命令长度固定为512字节。 |
CMD17 | adtc | [31:0]数据地址 | R1 | READ_SINGLE_BLOCK | 对于标准卡, 读取SEL_BLOCK_LEN长度字节的块;对于SDHC卡, 读取512字 节的块。 |
CMD18 | adtc | [31:0]数据地址 | R1 | READ_MULTIPLE_BLOCK | 连续从SD卡读取数据块, 直到被CMD12中断。 块长度同CMD17。 |
3.3 面向块的写操作(Class 4)
命令序号 | 类型 | 参数 | 响应 | 缩写 | 描述 |
---|---|---|---|---|---|
CMD24 | adtc | [31:0]数据地址 | R1 | WRITE_BLOCK | 对于标准卡, 写入SEL_BLOCK_LEN长度字节的块;对于SDHC卡, 写入512字 节的块。 |
CMD25 | adtc | [31:0]数据地址 | R1 | WRITE_MILTIPLE_BLOCK | 连续向SD卡写入数据块, 直到被CMD12中断。 每块长度同CMD17。 |
CMD27 | adtc | [31:0]填充位 | R1 | PROGRAM_CSD | 对CSD的可编程位进行编程 |
3.4 擦除命令(Class 5)
命令序号 | 类型 | 参数 | 响应 | 缩写 | 描述 |
---|---|---|---|---|---|
CMD32 | ac | [31:0]数据地址 | R1 | ERASE_WR_BLK_START | 设置擦除的起始块地址 |
CMD33 | ac | [31:0]数据地址 | R1 | ERASE_WR_BLK_END | 设置擦除的结束块地址 |
CMD38 | ac | [31:0]填充位 | R1b | ERASE | 擦除预先选定的块 |
3.5 加锁命令(Class 7)
命令序号 | 类型 | 参数 | 响应 | 缩写 | 描述 |
---|---|---|---|---|---|
CMD42 | adtc | [31:0]保留 | R1 | LOCK_UNLOCK | 加锁/解锁SD卡 |
3.6 特定应用命令(Class 8)
命令序号 | 类型 | 参数 | 响应 | 缩写 | 描述 |
---|---|---|---|---|---|
CMD55 | ac | [31:16]RCA[15:0]填充位 | R1 | APP_CMD | 指定下个命令为特定应用命令, 不是标准命令 |
CMD56 | adtc | [31:1]填充位[0]读/写 | R1 | GEN_CMD | 通用命令, 或者特定应用命令中, 用于传输一个数据块, 最低位为1表示读数据 , 为0表示写数据 |
3.7 SD卡特定应用命令
命令序号 | 类型 | 参数 | 响应 | 缩写 | 描述 |
---|---|---|---|---|---|
ACMD6 | ac | [31:2]填充位[1:0]总线宽度 | R1 | SET_BUS_WIDTH | 定义数据总线宽度(‘00’=1bit,’10’=4bit)。 |
ACMD13 | adtc | [31:0]填充位 | R1 | SD_STATUS | 发送SD状态 |
ACMD41 | bcr | [32]保留位[30]HCS(OCR[30]) [29:24]保留 位[23:0]VDD电压(OCR[23:0]) | R3 | SD_SEND_OP_COND | 主机要求卡发送它的支持信息(HCS)和OCR寄存器内容。 |
ACMD51 | adtc | [31:0]填充位 | R1 | SEND_SCR | 读取配置寄存器SCR |
五、SD卡响应
关于响应这一部分,我们可以参考文档 Physical Layer Simplified Specification v9.0 的 4.9 Responses一节。
1. 响应简介
响应由SD卡向主机发出,部分命令要求SD卡作出响应,这些响应多用于反馈SD卡的状态。 基本特性如下:
(1)总共有7个响应类型(代号: R1~R7),其中SD卡没有R4、 R5类型响应。特定的命令对应有特定的响应类型,比如当主机发送CMD3命令时,可以得到响应R6。
(2)与命令一样, SD卡的响应也是通过CMD线连续传输的。
(3)根据响应内容大小可以分为短响应和长响应。短响应是48bit长度,只有R2类型是长响应,其长度为136bit。
(4)除了 R3 类型之外,其他响应都使用 CRC7 校验来校验,对于 R2 类型是使用 CID 和 CSD 寄存器内部 CRC7。
2. R1(正常响应命令)
描述 | 起始位 | 传输位 | 命令号 | 卡状态 | CRC7 | 终止位 |
---|---|---|---|---|---|---|
Bit | 47 | 46 | [45:40] | [39:8] | [7:1] | 0 |
位宽 | 1 | 1 | 6 | 32 | 7 | 1 |
值 | “0” | “0” | x | x | x | “1” |
如果有传输到卡的数据,那么在数据线可能有busy信号。
3. R2(CID,CSD寄存器)
描述 | 起始位 | 传输位 | 保留 | [127:1] | 终止位 |
---|---|---|---|---|---|
Bit | 135 | 134 | [133:128] | 127 | 0 |
位宽 | 1 | 1 | 6 | x | 1 |
值 | “0” | “0” | “111111” | CID或者CSD寄存器[127:1]位的值 | “1” |
CID寄存器内容作为CMD2和CMD10响应, CSD寄存器内容作为CMD9响应。
4. R3(OCR寄存器)
描述 | 起始位 | 传输位 | 保留 | OCR寄存器 | 保留 | 终止位 |
---|---|---|---|---|---|---|
Bit | 47 | 46 | [45:40] | [39:8] | [7:1] | 0 |
位宽 | 1 | 1 | 6 | 32 | 7 | 1 |
值 | “0” | “0” | “111111” | x | “1111111” | “1” |
OCR寄存器的值作为ACMD41的响应。
5. R6(发布的RCA寄存器响应)
描述 | 起始位 | 传输位 | CMD3 | RCA寄存器 | 卡状态位 | CRC7 | 终止位 |
---|---|---|---|---|---|---|---|
Bit | 47 | 46 | [45:40] | [39:8] | [7:1] | 0 | |
位宽 | 1 | 1 | 6 | 16 | 16 | 7 | 1 |
值 | “0” | “0” | “000011” | x | x | x | “1” |
专用于命令CMD3的响应。
6. R7(发布的RCA寄存器响应)
描述 | 起始位 | 传输位 | CMD8 | 保留 | 接收电压 | 检测模式 | CRC7 | 终止位 |
---|---|---|---|---|---|---|---|---|
Bit | 47 | 46 | [45:40] | [39:20] | [19:16] | [15:8] | [7:1] | 0 |
位宽 | 1 | 1 | 6 | 20 | 4 | 8 | 7 | 1 |
值 | “0” | “0” | “001000” | “00000h” | x | x | x | “1” |
专用于命令CMD8的响应,返回卡支持电压范围和检测模式。
六、SD卡状态
这一部分我们可以参考文档 Physical Layer Simplified Specification v9.0 的 4.10 Three Status Information of SD Memory Card 这一小节,有关SD卡状态的那部分在4.10.2 SD Status。
1. 状态简介
这里以文档Physical Layer Simplified Specification v2.0来说明吧,因为在9.0版本中多了一个状态,但是似乎并不是目前关注的重点,而在2.0版本中是定义了种状态区域:
卡状态:执行命令的错误和状态信息,在响应中标示。
SD 状态:512 位的扩展状态信息,支持 SD 卡的特定功能以及将来的应用特定功能。
2. 卡状态
响应 R1 包含一个 32bit 的“卡状态”区域。这个区域用来传输卡的状态信息(可以被存在本地状态寄存器中)给主机。如果没有特别说明,这个状态总是同前一个命令相关。这里就不写了,具体可以查看 文档Physical Layer Simplified Specification v2.0 的 4.10.1 Card Status一节。
3. SD状态
SD 状态包含了与 SD 卡属性功能相关的状态位,可能会用于将来特定的应用命令。SD状态的大小是一个 512bit 的数据块。这个寄存器的内容与16位CRC会通过 DAT 总线传递给主机。SD 状态会通过 DAT 总线发送给主机,作为 ACMD13(前面是 CMD55)的响应。ACMD13 只能在“transfer”模式发送给已选定的卡。卡状态结构体在下表描述。“类型”和“清除条件”使用的缩写和卡状态一样。这一部分也不详细写,具体可以查看 文档Physical Layer Simplified Specification v2.0 的 4.10.2 SD Status一节。
七、SD卡时钟控制
这一部分我们可以参考文档 Physical Layer Simplified Specification v9.0 的 4.4 Clock Control 一节。
主机可以使用 SD 卡时钟信号来将卡改变到节电模式,或者控制总线上的数据流(避免不足或者超出的情况)。主机可以减小时钟频率,或者关闭时钟。比如,当主机带有 512Byte的数据缓存,却想要向 1kByte 的卡上写块。因此,为了保持连续的数据传输,从卡这边来看,卡的时钟需要在第一个 512Byte 后关闭时钟。然后主机会将另外 512Byte 数据填写到缓存中。当主机的写块的后半部分 ready 后,将会重启时钟,并继续发送数据。这样,卡就不会意识到数据传输的中断。
这里有一些限制,主机需要注意:
总线时钟可在任何时候改变(要小于最大数据传输频率和本规范定义的标示频率),但是有个例外,那就是ACMD41(SD_APP_OP_COND)命令。当 ACMD41 发送后,主机应该执行下面的(1)和(2)两个步骤,直到卡变为 ready 状态。
(1)发送连续的时钟,频率在 100KHz~400KHz;
(2)如果主机想要停止时钟,通过 ACMD41 循环设置 busy 位,小于 50ms 间隔。
八、SD卡操作模式及切换
这一部分我们可以参考文档 Physical Layer Simplified Specification v9.0 的 4.2 Card ldentification Mode 和 4.3 Data Transfer Mode 两个小节。
1. 操作模式
SD卡有多个版本, STM32控制器目前最高支持《Physical Layer Simplified Specification V2.0》定义的SD卡, STM32控制器对SD卡进行数据读写之前需要识别卡的种类: V1.0标准卡、 V2.0标准卡、 V2.0高容量卡或者不被识别卡。
SD卡系统(包括主机和SD卡)定义了两种操作模式: 卡识别模式和数据传输模式。 在系统复位后,主机处于卡识别模式,寻找总线上可用的SDIO设备;同
时, SD卡也处于卡识别模式,直到被主机识别到,即当SD卡接收到SEND_RCA(CMD3)命令后, SD卡就会进入数据传输模式,而主机在总线上所有卡被识别后也进入数据传输模式。
2. 不同模式下SD卡状态
在每个操作模式下,SD卡都有几种状态, 通过命令控制实现卡状态的切换 :
操作模式 | SD卡状态 |
无效模式(Inactive) | 无效状态(Inactive State) |
卡识别模式(Card identification mode) | 空闲状态(Idle State) |
准备状态(Ready State) | |
识别状态(Identification State) | |
数据传输模式(Data transfer mode) | 待机状态(Stand-by State) |
传输状态(Transfer State) | |
发送数据状态(Sending-data State) | |
接收数据状态(Receive-data State) | |
编程状态(Programming State) | |
断开连接状态(Disconnect State) |
3. 卡识别模式
在卡识别模式下,主机会复位所有处于“卡识别模式”的SD卡,确认其工作电压范围,识别SD卡类型,并且获取SD卡的相对地址(卡相对地址较短,便于寻址)。在卡识别过程中,要求SD卡工作在识别时钟频率FOD的状态下。
(1)上电后,所有卡处于空闲状态,包括当前处于无效状态的卡,主机也可以发送GO_IDLE_STATE(CMD0)让所有卡软复位从而进入空闲状态,但当前处于无效状态的卡并不会复位。
(2)主机在开始与卡通信前,需要先确定双方在互相支持的电压范围内。 SD 卡有一个电压支持范围,主机当前电压必须在该范围可能才能与卡正常通信。 SEND_IF_COND(CMD8) 命令就是用于验证卡接口操作条件的 (主要是电压支持)。卡会根据命令的参数来检测操作条件匹配性,如果卡支持主机电压就产生响应,否则不响应。而主机则根据响应内容确定卡的电压匹配性。 CMD8 是 SD卡标准 V2.0 版本才有的新命令,所以如果主机有接收到响应,可以判断卡为 V2.0 或更高版本SD 卡(非MMC卡)。
(3)使用SD_SEND_OP_COND(ACMD41)命令识别或拒绝不匹配它的电压范围的卡。 并通过HCS位及其响应判断是SDSC还是SDHC卡。ACMD41 命令的VDD 电压参数用于设置主机支持电压范围,卡响应会返回卡支持的电压范围。对于对 CMD8有响应的卡,把 ACMD41 命令的 HCS 位设置为 1,可以测试卡的容量类型,如果卡响应的 CCS 位为 1 说明为高容量 SD 卡,否则为标准卡。卡在响应 ACMD41 之后进入准备状态,不响应 ACMD41的卡为不可用卡,进入无效状态。 ACMD41 是应用特定命令,发送该命令之前必须先发 CMD55。
(4)使用ALL_SEND_CID(CMD2) 来控制所有卡返回它们的卡识别号(CID),处于准备状态的卡在发送CID之后就进入识别状态。
(5)主机 发送SEND_RELATIVE_ADDR(CMD3)命令,让卡自己推荐一个相对地址(RCA)并响应命令。这个RCA是16bit地址,而CID是128bit地址,使用RCA简化通信。
(6)卡在接收到CMD3并发出响应后就进入数据传输模式,并处于待机状态,主机在获取所有卡RCA之后也进入数据传输模式。
4. 数据传输模式
只有SD卡系统处于数据传输模式下才可以进行数据读写操作。数据传输模式下可以将主机SD时钟频率设置为FPP,默认最高为25MHz,频率切换可以通过CMD4命令来实现。
(1)CMD7用来选定和取消指定的卡,卡在待机状态下还不能进行数据通信,因为总线上可能有多个卡都是出于待机状态,必须选择一个RCA地址目标卡使
其进入传输状态才可以进行数据通信。同时通过CMD7命令也可以让已经被选择的目标卡返回到待机状态。
(2)数据传输模式下的数据通信都是主机和目标卡之间通过寻址命令点对点进行的。卡处于传输状态下可以使用块的读写以及擦除命令对卡进行数据读写、擦除。
(3)CMD12可以中断正在进行的数据通信,让卡返回到传输状态。 CMD0和CMD15会中止任何数据编程操作,返回卡识别模式,这可能导致卡数据被损坏。
九、读写SD卡
1. 初始化
要实现SDIO驱动SD卡,最重要的步骤就是SD卡的初始化,只要SD卡初始化完成了,那么剩下的(读写操作)就简单了,所以我们这里重点介绍SD卡的初始化。这一部分可以参考文档 Physical Layer Simplified Specification v9.0 的4.2.3 Card lnitialization and ldentification Process一节。
(1)从SD卡初始化流程可知,不管什么卡(这里我们将卡分为4类:SD2.0高容量卡(SDHC,最大32G),SD2.0标准容量卡(SDSC,最大2G),SD1.x卡和MMC卡),首先我们要执行的是卡上电(设置SDIO_POWER[1:0]=11),上电后发送CMD0,对卡进行软复位.
(2)之后发送CMD8命令,用于区分SD卡2.0,只有2.0及以后的卡才支持CMD8命令,MMC卡和V1.x的卡,是不支持该命令的。 CMD8命令格式如下表(见 文档 Physical Layer Simplified Specification v9.0 的4.9.6 R7(Card interface condition)):
在发送CMD8的时候,通过其带的参数我们可以设置VHS位(在v9.0上叫Voltage accepted),以告诉SD卡,主机的供电情况,让SD卡知道主机的供电范围。VHS位(在v9.0上叫Voltage accepted)定义如下表所示:
这里我们使用参数0X1AA,即告诉SD卡,主机供电为2.7~3.6V之间,如果SD卡支持CMD8,且支持该电压范围,则会通过CMD8的响应(R7)将参数部分原本返回给主机,如果不支持CMD8,或者不支持这个电压范围,则不响应。
(3)在发送CMD8后,发送ACMD41(注意:发送ACMD41之前,要先发送CMD55),来进一步确认卡的操作电压范围,并通过HCS位来告诉SD卡,主机是不是支持高容量卡(SDHC)。ACMD41命令格式如下表所示:
ACMD41指令响应(R3),包含了SD卡OCR寄存器内容,其定义如下表所示:
对于支持CMD8的卡,主机设置ACMD41的参数HCS=1,告诉SD卡,主机支持SDHC卡。对2.0的卡,OCR的CCS位用于表示SDHC还是SDSC;对1.x的卡,则忽略该位;对MMC卡,则不支持ACMD41,MMC卡只需要发送:CMD0和CMD1即可完成初始化。
(4)CMD2用于获取CID寄存器数据,CID寄存器各位定义如下表:
SD卡在收到CMD2后,将返回R2长响应(136位),其中包含128位有效数据(CID寄存器内容),存放在SDIO_RESP1~4等4个寄存器里面。通过读取这四个寄存器,就可以获得SD卡的CID信息。
(4)CMD3,用于设置卡相对地址(RCA,必须为非0),对于SD卡(非MMC卡),在收到CMD3后,将返回一个新的RCA给主机,方便主机寻址。RCA的存在允许一个SDIO接口挂多个SD卡,通过RCA来区分主机要操作的是哪个卡。对于MMC卡,则不是由SD卡自动返回RCA,而是主机主动设置MMC卡的RCA,即通过CMD3带参数(高16位用于RCA设置),实现RCA设置。同样MMC卡也支持一个SDIO接口挂多个MMC卡,不同于SD卡的是所有的RCA都是由主机主动设置的,而SD卡的RCA则是SD卡发给主机的。在获得卡RCA之后,我们便可以发送CMD9(带RCA参数),获得SD卡的CSD寄存器内容,从CSD寄存器,我们可以得到SD卡的容量和扇区大小等十分重要的信息。CSD寄存器我们可以参考文档 Physical Layer Simplified Specification v9.0 的5.3.1 CSD STRUCTURE一节。
(5)至此,我们的SD卡初始化基本就结束了,最后通过CMD7命令,选中我们要操作的SD卡,即可开始对SD卡的读写操作了。
2. 数据块读取
关于读取我们可以参文档 Physical Layer Simplified Specification v9.0 的 4.3.3 Data Read 一节。
2.1 单块数据块读取流程
单块数据块读取大概得流程如下:
2.2 多块数据块读取流程
2.3 相关命令说明
2.3.1 CMD17命令
2.3.2 CMD18命令
2.3.3 CMD12命令
3. 数据块写入
关于写入我们可以参考文档 Physical Layer Simplified Specification v9.0 的 4.3.4 Data Write 一节。
3.1 单块数据块写入流程
3.2 多块数据写入流程
3.3 相关命令说明
3.3.1 CMD13命令
R1响应如下:
3.3.2 CMD24命令
3.3.3 ACMD23命令
注意:发送ACMD之前,必须先发送CMD55,通知SD卡,接下来要发送的是应用命令(APP CMD),而非标准命令。
3.3.4 CMD55命令
3.3.5 CMD25命令
4. 读写地址
4.1 写命令CMD24
我们可以参考文档 Physical Layer Simplified Specification v9.0 的4.7.4 Detailed Command Description一节,上边会有CMD24的说名,如上图所示,我们发送CMD24命令的时候携带的参数就是写入的地址信息,他是一个32位的长度,一共就是可以表示这么多个“地址”:
1 | 2 ^ 32 = 4 * 2^10 * 2^10 |
那么这是怎么对应SD卡的地址的呢?要是每个字节都对应一个地址,那这完全不够32GB的用啊,2GB的还。其实我们看手册的话,手册这里有一个脚注:
这句话就在文档 Physical Layer Simplified Specification v9.0 的Table 4-24 : Block-Oriented Read Commands (class 2)这一个命令组的下边,这句话的意思就是,对于SDSC卡来说,单位就是字节,对于SDHC或者SDXC卡来说,使用块为单位,也就是512个字节,这什么意思呢,意思就是:
1 | 对于SDSC卡: |
这样计算下来的话,32位的地址,以512字节为单位,就可以表示:
1 | 4 * 2^10 * 2^10 * 512 = 2048 * 2^10 * 2^10 = 2 * 2^10 * 2^10 * 2^10 = 2TB |
这样的话32位不就够最大2TB的卡使用了嘛,这也就是为什么我们初始化SD卡的时候要获取卡的类型,读写的时候要先确定块的长度的原因啦。我们还可以查看 文档 Physical Layer Simplified Specification v9.0 的 4.3 Data Transfer Mode中 4.3.3 Data Read 和 4.3.4 Data Write两个部分,里边也有对应的说明。
4.2 卡的类型
我们在看SD卡初始化流程的时候会发现,我们发送了ACMD41命令,这个命令上边有说明,我们再看一下手册(我们可以参考文档 Physical Layer Simplified Specification v9.0 的 4.2.3.1 Initialization Command (ACMD41)),详细了解一下:
可以看到,我们这里收到响应的时候,有一个CCS位,当CCS=1 表示卡是高容量 SD 卡(SDHC或者SDXC);CCS=0 表示卡是普通 SD 卡(SDSC)。