当前位置: 首页 > ops >正文

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 10x00[39:32]保留或高位地址(无用)
Byte 20x00[31:24]保留或地址(无用)
Byte 30x01[23:16]供电电压范围,0x01 表示支持 2.7V ~ 3.6V
Byte 40xAA[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 模式下无法充分发挥。

四、其他相关链接

1、SPI协议详细总结附实例图文讲解通信过程
2、uboot下spi master和flash驱动开发
3、 Flash闪存储存原理以及NAND flash、NOR flash对比总结
http://www.xdnf.cn/news/15193.html

相关文章:

  • 分层架构的C++高并发内存池性能优化
  • 无法打开windows安全中心解决方案
  • DirectX Repair修复工具下载,.NET修复,DirectX修复
  • 2025 全球酒店用品厂家竞争力排行榜发布:扬州卓韵领衔,布草工厂实力重塑行业格局
  • 关于 验证码系统 详解
  • Android音视频探索之旅 | C++层使用OpenGL ES实现音频渲染
  • Python数据容器-集合set
  • 《硬件产品经理》第八章:产品生产制造
  • Android 系统默认Launcher3 菜单模式双层改成单层-3
  • 【设计模式】适配器模式(包装器模式),缺省适配器模式,双向适配器模式
  • 带货视频评论洞察 Baseline 学习笔记 (Datawhale Al夏令营)
  • Ntfs!LfsFlushLfcb函数分析之while的循环条件NextLbcb的确定和FirstLbcb->LbcbFlags的几种情况
  • OpenVela之模拟器调试
  • Go内存分配
  • vite如何生成gzip,并在服务器上如何设置开启
  • 如何在 Windows 10 上安装 RabbitMQ
  • 如何在 Visual Studio Code 中使用 Cursor AI
  • 【嵌入式硬件实例】-555定时器实现倍压电路
  • C语言:20250712笔记
  • 系统学习Python——并发模型和异步编程:基础实例-[使用线程实现旋转指针]
  • Ruby如何采集直播数据源地址
  • tiktok 弹幕 逆向分析
  • 后端定时过期方案选型
  • Linux/Ubuntu安装go
  • ​Windows API 介绍及核心函数分类表
  • MySQL 5.7.29升5.7.42实战:等保三漏洞修复+主从同步避坑指南
  • 一分钟快速了解Apache
  • Ether and Wei
  • 【android bluetooth 协议分析 07】【SDP详解 2】【SDP 初始化】
  • 详解缓存淘汰策略:LRU