SD卡初始化、命令及响应命令格式(详细)讲解
目录
- 一、简介
- 二、详细介绍
- 2.1 引脚定义
- 2.2 SD卡寄存器
- 2.3 命令格式
- 2.4 SD卡读写操作
- 2.4.1 读过程
- 2.4.2 写过程
- 2.5 MMC和SD区别
- 2.6 SD卡识别过程
- 2.6.1 复位初始化
- 2.6.2 SD卡版本确认
- 2.6.3 SD卡初始化
- 2.6.4 CMD58
- 2.6.5 读取单个扇区(512字节)流程
- 2.6.6 写单个扇区(512字节)流程
- 2.6.7 SD卡响应值
- 1、 常见返回值(R1)
- 2、 R2 响应(2 字节)—— CMD13 使用(发送卡状态)
- 3、 R3 响应(5 字节)—— 用于 CMD58(读取OCR寄存器)
- 4、 R7 响应(5 字节)—— 用于 CMD8(检查卡电压范围)
- 三、性能分析
- 四、其他相关链接
- 1、SPI协议详细总结附实例图文讲解通信过程
- [2、uboot下spi master和flash驱动开发](https://blog.csdn.net/Luckiers/article/details/131298180)
- [3、 Flash闪存储存原理以及NAND flash、NOR flash对比总结](https://blog.csdn.net/Luckiers/article/details/124247378)
一、简介
SD卡(Secure Digital Memory Card)在我们生活中已经非常普遍了, 控制器对SD卡进行读写通信操作一般有两种通信接口可选,一种是SPI接口,另外一种是SDIO接口。
SDIO全称是安全数字输入/输出接口,多媒体卡(MMC)、SD卡、SD I/O卡(专指使用SDIO接口的一些输入输出设备)都可使用SDIO接口通讯。 STM32F10x系列控制器有一个SDIO主机接口,它支持与上述使用SDIO接口的设备进行数据传输。
二、详细介绍
2.1 引脚定义
SD卡使用9-pin的接口,其中3根电源线、1根时钟线、1根命令线和4根数据线,具体说明如下:
CLK:同步时钟线,由SDIO主机产生,即由STM32控制器输出;使用SPI模式时,该引脚与SPI总线的SCK时钟信号相连;
CMD:命令控制线,SDIO主机通过该线发送命令控制SD卡,如果命令要求SD卡提供应答(响应),SD卡也是通过该线传输应答信息; 使用SPI模式时,该引脚与SPI总线的MOSI信号相连,SPI主机通过它向SD卡发送命令及数据,但因为SPI总线的MOSI仅用于主机向从机输出信号,所以SD卡 返回应答信息时不使用该信号线;
D0-3:在SDIO模式下,它们均为数据线,传输读写数据,SD卡可将D0拉低表示忙状态;在SPI模式下,D0与SPI总线的MISO信号相连, SD卡通过该信号线向主机发送数据或响应,D3与总线的CS信号相连,SPI主机通过该信号线选择要通讯的SD卡。
VDD、VSS1、VSS2:电源和地信号,其中Micro SD卡不包含VSS2信号,即Micro SD卡仅有8根线。
2.2 SD卡寄存器
SD卡总共有8个寄存器,用于设定或表示SD卡信息,参考表 SD卡寄存器。 这些寄存器只能通过对应的命令访问,对SD卡进行控制操作并不是像操作控制器GPIO相关寄存器那样一次读写一个寄存器, 它是通过命令来控制的,SD卡定义了64个命令(部分命令不支持SPI模式),每个命令都有特殊意义,可以实现某一特定功能, SD卡接收到命令后,根据命令要求对SD卡内部寄存器进行修改,程序控制中只需要发送组合命令就可以实现SD卡的控制以及读写操作。
2.3 命令格式
起始位和终止位:命令的主体包含在起始位与终止位之间,它们都只包含一个数据位,起始位为0,终止位为1。
传输标志:用于区分传输方向,该位为1时表示命令,方向为主机传输到SD卡,该位为0时表示响应,方向为SD卡传输到主机。
命令主体内容包括命令、地址信息/参数和CRC校验三个部分。
命令号:它固定占用6bit,所以总共有64个命令(代号:CMD0~CMD63),每个命令都有特定的用途, 部分命令不适用于SPI总线,或不适用于SD卡操作,只是专门用于MMC卡或者SD I/O卡。
地址/参数:每个命令有32bit地址信息/参数用于命令附加内容,例如,广播命令没有地址信息,这32bit用于指定参数, 而寻址命令这32bit用于指定目标SD卡的地址,当使用SDIO驱动多张SD卡时,通过地址信息区分控制不同的卡,使用SPI总线驱动时, 通过片选引脚来选择不同的卡,所以使用这些命令时地址可填充任意值。
CRC7校验:长度为7bit的校验位用于验证命令传输内容正确性,如果发生外部干扰导致传输数据个别位状态改变将导致校准失败, 也意味着命令传输失败,SD卡不执行命令。使用SDIO驱动时,命令中必须包含正确的CRC7校验值;而使用SPI驱动时, 命令中的CRC7校验默认是关闭的,即这CRC7校验位中可以写入任意值而不影响通讯,仅在发送CMD0命令时需要强制带标准的CRC7校验。
2.4 SD卡读写操作
读写操作都是由主机发起的,主机发送不同的命令表示读或写,SD卡接收到命令后先针对命令返回响应。在读操作中, SD卡返回一个数据块,数据块中包含CRC校验码;在写操作中,主机接收到命令响应后需要先发送一个标志(TOKEN)然后紧跟一个要写入的数据块, 卡接收完数据块后回反回一个数据响应及忙碌标志,当SD卡把接收到的数据写入到内部存储单元完成后,会停止发送忙碌标志,主机确认SD卡空闲后,可以发送下一个命令。
2.4.1 读过程
读过程:
(1) 拉低片选信号,调用SD_SendCmd向SD卡发送CMD17命令以及命令参数(即要读取的地址ReadAddr)
(2) SD卡接收到该命令后,将会返回一个字节的R1响应、 一个字节的单块数据读取Token、一个从ReadAddr地址开始的数据块内容、2个字节的CRC校验码
(3) 接收到R1响应后,检查SD卡是否返回单块数据读取的Token,Token值为0xFE
(4) 接收到Token, 使用for循环接收长度为BlockSize个字节的数据
(5) 读取完数据后,SD卡还返回2个字节的CRC校验码,SD卡在SPI模式下不进行校验,但还是要让SD卡完成发送流程,所以调用2次write 以产生时钟驱动SD卡输出校验码。
2.4.2 写过程
(1) 拉低片选信号,调用SD_SendCmd向SD卡发送CMD24命令以及命令参数(即要写入的地址WriteAddr)
(2) 接收到R1响应后,向SD卡发送单块数据开始的Token:0xFE
(3) SD卡接收到此Token值后,将把后续接收到的字节理解成要写入的数据
(4) 循环写入长度为BlockSize个字节的数据
(5) 写入完数据后,还继续向SD卡发送2个字节的CRC校验码,虽然SD卡在SPI模式下默认不进行校验,但还是要完成发送流程,所以发送了两个0xFF。
2.5 MMC和SD区别
项目 | MMC 卡 | SD 卡 |
---|---|---|
推出时间 | 1997 年(由SanDisk和Siemens) | 1999 年(由SanDisk、Panasonic和Toshiba) |
设计目标 | 通用存储设备 | 更安全的消费类存储,带版权保护 |
外形尺寸 | 通常与标准 SD 卡相同,但略薄(1.4 mm) | 标准厚度为 2.1 mm |
引脚数量 | 最初 7 引脚,后扩展到13(eMMC为BGA) | 9 引脚(更多功能支持) |
接口协议 | MMC协议(可选SPI模式) | SD协议(也支持SPI模式) |
最大容量 | 理论支持至2TB,但不常见 | SDHC(32GB),SDXC(2TB),SDUC(128TB) |
数据传输速度 | 较慢(原始MMC ~20MB/s) | 更快(SD UHS-I、UHS-II、UHS-III,速度达624MB/s以上) |
安全特性 | 无 DRM(数字版权管理) | 内建CPRM(内容保护)机制 |
主流支持情况 | 几乎淘汰(嵌入式eMMC仍使用) | 市场主流,广泛应用于相机、手机等 |
安装方式 | BGA焊接在主板上 | 可插拔 |
应用场景 | 手机、平板、嵌入式系统 | 相机、存储卡 |
可替换性 | 不可更换 | 可更换 |
协议 | JEDEC eMMC协议 | SD协议 |
性能 | 稳定、便宜、慢于UFS | 视SD等级而定,UHS/SD Express更快 |
2.6 SD卡识别过程
控制器对SD卡进行数据读写之前需要识别卡的种类:MMC卡、V1.0标准卡、V2.0标准卡、V2.0高容量卡或者不被识别卡, 见图 卡识别流程。因为版本众多,SD卡系统(包括主机和SD卡)定义了两种操作模式:卡识别模式和数据传输模式。 在系统复位后,主机处于卡识别模式,以寻找总线上可用的设备,区分出不同各类的卡; 同时,SD卡也处于卡识别模式,直到被主机识别到,之后SD卡就会进入数据传输模式。
2.6.1 复位初始化
MMC卡在 SPI 模式下不能立即工作,必须先执行初始化流程:
(1)发送80个时钟(拉高CS并发送10个0xFF)
(2)发送 CMD0(复位命令)
命令格式: 0x40 | cmd(6位命令) + 参数(32位) + CRC(8位)
CMD0: GO_IDLE_STATE
主机发送: 0x40 00 00 00 00 95
若卡正确响应,将返回 R1响应:0x01(表示处于 Idle 状态)
2.6.2 SD卡版本确认
SD 卡 CMD8 命令(发送接口条件)是 SD 卡初始化过程中的关键命令,用于确定卡的电压范围和支持的电气标准
字节位置 含义 数值 / 说明
第 1 字节 命令标志 + 命令号 0x48(最高位为 0,其余 7 位为命令号 8 → 0x08,故 0x00 + 0x08 = 0x48)
第 2-5 字节 32 位参数(Argument) 包含电气特性和校验模式,具体格式见下文。
第 6 字节 CRC 校验 + 结束位 SPI 模式下固定为0x87(CRC7 值为 0x07,最高位补 1 → 0x07 | 0x80 = 0x87)
典型 CMD8 命令示例
检查卡是否支持 2.7V-3.6V 电压,校验模式设为 0xAA:
命令:0x48 0x00 0x00 0x01 0xAA 0x87
第 1 字节:0x48(CMD8 命令号);
第 2-3 字节:0x00 0x00(保留位);
第 4 字节:0x01(VHS=0x01,表示 2.7V-3.6V);
第 5 字节:0xAA(校验模式);
第 6 字节:0x87(固定 CRC)。
2.6.3 SD卡初始化
发送 CMD1(MMC 初始化) 或 ACMD41(SD卡)来等待卡初始化完成。
MMC卡:发送 CMD1 直到返回 0x00
SD卡:发送 CMD55 + ACMD41
2.6.4 CMD58
CMD58命令以读取OCR寄存器的CCS位,接收SD卡的响应,若CCS=0,则表示该卡为SDSC卡(容量小于等于2GB),若CCS=1,则表示该卡为SDHC卡(容量大于2GB)
2.6.5 读取单个扇区(512字节)流程
选中 CS(拉低)
发送 CMD17(读单块):0x51 + block address + CRC
等待响应(R1 响应应为 0x00)
等待数据起始标志(0xFE)
连续读取 512 字节数据
读取 2 字节 CRC(可忽略)
拉高 CS
第 1 字节 命令标志 + 命令号 0x51
第 2-5 字节 32 位数据块地址参数 需读取的块起始地址(单位:字节),需对齐到块大小(如 512 字节块,地址为 512 的整数倍)。
例如:读第 2 块(地址 = 2×512=0x00000400),则这 4 字节为0x00 0x00 0x04 0x00。
第 6 字节 CRC 校验 + 结束位 SPI 模式下可忽略 CRC,直接填0xFF(结束位为 1,低 7 位随意)。
2.6.6 写单个扇区(512字节)流程
写数据比读复杂一点,需要写命令 → 等待响应 → 发0xFE → 发数据 → CRC → 等待写入完成。
简要步骤如下:
发送 CMD24(写单块)
等待 R1 响应 0x00
发送数据起始标志 0xFE
发送 512 字节数据
发送 2 字节 CRC(可为0)
等待响应令牌(0x05 表示数据接受成功)
等待写入完成(卡返回0xFF)
2.6.7 SD卡响应值
1、 常见返回值(R1)
值 含义
0x01 卡处于空闲状态(刚上电)
0x00 操作成功(无错误)
0x05 命令非法+空闲(常见于CMD8)
0x04 命令非法
0xFF 卡未响应(无回应或错误)
2、 R2 响应(2 字节)—— CMD13 使用(发送卡状态)
第一字节是 R1 格式,第二字节是状态位。
Bit 含义
Bit 0 卡被锁定
Bit 1 写保护擦除失败
Bit 2 锁/解锁命令失败
Bit 3 命令 CRC 校验错误
Bit 4 非法命令
Bit 5 擦除参数错误
Bit 6 地址错误
Bit 7 参数错误
在 SPI 模式下:
主机发送命令后,会等待最多 8 个字节的 0xFF 来等响应;
正确响应值不会是 0xFF,而是前面列的响应码;
主机通常通过读取直到不是 0xFF 的第一个字节,即为响应开始。
3、 R3 响应(5 字节)—— 用于 CMD58(读取OCR寄存器)
字节1:R1 响应
字节2-5:OCR(操作条件寄存器),bit31 表示是否支持3.3V
示例响应:
响应:0x00 0xFF 0x80 0x00 0x00
→ OK OCR内容:支持3.2~3.4V
响应数据:0x00 0xFF 0x80 0x00 0x00
↑ ↑ ↑ ↑ ↑
R1 OCR[31:24] OCR[23:16] OCR[15:8] OCR[7:0]
第1字节:0x00
这是 R1 响应,表示无错误,卡已准备好。
0x01 表示卡仍在初始化中(Idle)
0x00 表示卡已完成初始化
第2~5字节:OCR 寄存器(4 字节)
OCR 全称 Operation Conditions Register(操作条件寄存器),格式如下(高位在前):
Bit 31 :卡是否为高容量(CCS)
Bit 30–28 :保留
Bit 27–15 :电压范围(常用的电压段)
Bit 14–8 :保留
Bit 7–0 :忙碌位/保留
现在我们解析 0xFF 0x80 0x00 0x00:
转换为二进制:
0xFF = 11111111
0x80 = 10000000
0x00 = 00000000
0x00 = 00000000
合并为 OCR 32位值(从 Bit31 开始):
Bit 31 : 1 → 支持高容量(SDHC/SDXC)
Bit 30–28 : 111
Bit 27–24 : 1xxx
Bit 23–15 : x00000000
其余均为0
重点:Bit 23–15 是电压窗口
根据 SD 规范:
Bit 电压范围
20 2.7V - 2.8V
21 2.8V - 2.9V
22 2.9V - 3.0V
23 3.0V - 3.1V
24 3.1V - 3.2V
25 3.2V - 3.3V
26 3.3V - 3.4V
27 3.4V - 3.5V
28 3.5V - 3.6V
而你返回的是:
0xFF 0x80 … → 即 Bit 31–24 = 11111111 10000000
这表示:
Bit 31 = 1 → 是 SDHC/SDXC(高容量卡)
Bit 30–24(电压支持)中,从 Bit 27 到 Bit 20 全为 1 → 表示支持从 2.7V 到 3.6V 的电压范围
所以这张卡支持常见的 3.3V 电压 ?
4、 R7 响应(5 字节)—— 用于 CMD8(检查卡电压范围)
字节1:R1 响应字节2-5:回显 CMD8 的参数,主要是检查电压是否支持
示例响应:
发送 CMD8 参数:0x00 0x00 0x01 0xAA
响应:0x01 0x00 0x00 0x01 0xAA
发送 CMD8 参数:0x00 0x00 0x01 0xAA
→ 卡支持 2.7~3.6V,兼容 SDHC/SDXC
字节编号 | 内容 | 位段 | 说明 |
---|---|---|---|
Byte 1 | 0x00 | [39:32] | 保留或高位地址(无用) |
Byte 2 | 0x00 | [31:24] | 保留或地址(无用) |
Byte 3 | 0x01 | [23:16] | 供电电压范围,0x01 表示支持 2.7V ~ 3.6V |
Byte 4 | 0xAA | [15:8] | 校验模式值(推荐固定为 0xAA) |
CRC | 必须有效 | - | 通常为 0x87(CMD8要求CRC校验) |
响应:0x01 0x00 0x01 0xAA
↑ ↑ ↑ ↑
Idle OK 电压支持 模式回显
三、性能分析
接口差异:
原生 SDIO 模式:采用专用的 4 线或 8 线数据总线,最高数据传输速率能达到 312MB/s(UHS-II)。
SPI 模式:基于 SPI 协议,仅使用 4 根信号线(CLK、MOSI、MISO、CS),数据传输速率相对较低。
SPI 模式的速率限制:
理论上 SPI 模式的最高速率可达 50MHz(约 25MB/s),但实际应用中,受限于内核驱动和硬件性能,通常只能达到几 MB/s。
这就意味着,SDXC 卡的高速性能(如 U3 等级)在 SPI 模式下无法充分发挥。