1. SD卡协议基础:物理层规范、命令格式、响应类型、SPI与SDIO模式对比
各位同学,咱们今天正式开讲SD卡。说实话,SD卡这玩意儿看着不起眼,但里面的协议细节真不少。我当年第一次调SD卡驱动时,被那些命令和响应搞得晕头转向,折腾了整整三天才把初始化流程跑通。嗯,今天咱们就把这些基础打扎实。
1.1 物理层规范:你得知道的硬件底子
SD卡物理层,说白了就是卡和主控之间怎么连、怎么传数据。SD卡有9个引脚,但不同模式下用的引脚不一样。
引脚定义速览:
- VDD / VSS:电源和地。SD卡工作电压范围挺宽,2.7V到3.6V都行。我遇到过有人用3.3V供电结果卡不识别,后来发现是电源纹波太大,加个电容就好了。
- CLK:时钟线。所有数据都在时钟上升沿采样。SDIO模式下时钟频率可以到50MHz,SPI模式一般25MHz封顶。
- CMD:命令线。双向传输,主控发命令,卡回响应。
- DAT0-DAT3:数据线。SDIO模式下可以1位、4位并行传输。SPI模式下只用DAT0做MISO,CMD做MOSI。
核心要点:SD卡上电后默认工作在1位SDIO模式。想切到4位模式或者SPI模式,得通过命令去配置。这个顺序搞反了,卡就不理你。
1.2 命令格式:主控和卡怎么说话
SD卡的命令是48位的固定格式。我刚开始看手册时觉得这格式挺啰嗦,但后来发现设计得其实很严谨。
命令格式拆解:
- Bit 47:起始位,固定为0
- Bit 46:传输方向位,主控发命令时为1
- Bit 45-40:命令索引(CMD0-CMD63),共6位
- Bit 39-8:命令参数,32位。比如CMD16设置块长度,参数就是块大小值
- Bit 7-1:CRC7校验,覆盖命令索引和参数
- Bit 0:结束位,固定为1
// 命令格式示意(伪代码)
typedef struct {
uint8_t start_bit : 1; // 0
uint8_t tx_bit : 1; // 1
uint8_t cmd_index : 6; // CMD0~CMD63
uint32_t argument : 32; // 参数
uint8_t crc7 : 7; // CRC校验
uint8_t end_bit : 1; // 1
} sd_cmd_t;
个人经验:CRC7计算可以用查表法,速度比逐位计算快很多。我早期代码里用逐位算,结果在50MHz时钟下CPU占用率飙到30%,换成查表后降到2%以下。
1.3 响应类型:卡怎么回话
卡收到命令后,会根据命令类型返回不同格式的响应。常见的响应类型有R1、R2、R3、R6、R7等。我当年最头疼的就是记这些响应格式,后来画了个表才理清楚。
常用响应类型对比:
| 类型 | 长度 | 包含内容 | 典型命令 |
|---|---|---|---|
| R1 | 48位 | 状态位(忙、擦除、超时等) | CMD0、CMD2、CMD9 |
| R2 | 136位 | CID或CSD寄存器内容 | CMD2、CMD9 |
| R3 | 48位 | OCR寄存器内容(电压范围) | CMD8 |
| R6 | 48位 | RCA地址 + 状态位 | CMD3 |
| R7 | 48位 | 电压匹配信息 + 检查模式 | CMD8 |
避坑指南:我曾经在调试时发现卡总返回0xFF,查了半天才发现是SPI模式下CMD0发完后,卡需要至少74个时钟周期才能准备好响应。嗯,这个延时不能省。
1.4 SPI与SDIO模式对比:选哪个更合适
SD卡支持两种通信模式:SPI和SDIO。很多初学者会问:到底用哪个?我的建议是:看你的主控资源。
两种模式的核心差异:
- 引脚数量:SPI模式只用3根线(CLK、MOSI、MISO),外加片选CS。SDIO模式至少需要6根线(CLK、CMD、DAT0-DAT3)。
- 传输速度:SDIO 4位模式理论速度是SPI的4倍。实际项目中,SDIO读速度能到20MB/s以上,SPI一般5MB/s左右。
- 协议复杂度:SPI模式简单,命令和响应都是字节流。SDIO模式有命令、响应、数据块、CRC校验,逻辑复杂不少。
- 命令兼容性:SPI模式下有些命令和响应格式跟SDIO不一样。比如SPI模式下CMD0返回R1,SDIO模式下返回R1但格式有差异。
我的选择原则:如果主控有硬件SDIO控制器,优先用SDIO模式,速度快。如果主控资源紧张(比如小单片机),或者只需要低速读写(比如存配置参数),SPI模式更省事。
1.5 知识体系总览
下面这张图把本章的核心知识点串起来了。你想想看,SD卡协议其实就三块:物理层怎么连、命令怎么发、响应怎么收。SPI和SDIO是两种不同的"方言"。
这张图把物理层、命令响应、模式对比三层关系理清了。我个人习惯是先看物理层能不能对上,再调命令交互,最后根据项目需求选模式。顺序搞反了,后面调试会很痛苦。
小技巧:刚开始调SD卡驱动时,先用SPI模式把读写流程跑通,再切到SDIO模式优化速度。这样能隔离问题,不至于同时面对协议和时序两座大山。