SD卡的命令格式
SD卡的指令由6个字节组成,字节1的最高2位固定为01,低6位为命令号(比如CMD16,为10000即16进制的0X10,完整的CMD16,第一个字节为 01010000,即 0X10+0X40)。
字节2~5为命令参数,有些命令是没有参数的。
字节6的高7位为CRC值,最低位恒定为1。
SD卡的命令总共有12类,分为Class0~Class11
SPI模式下的命令表
几个主要的命令
完整的命令介绍请查看手册:附链接
其中 “命令”是主机发送的,“回应”是从机(SD卡)回复的,“回应”的意义在于告诉主机命令的执行状态。“回应”有固定的回应格式,比如 R1、R3、R7
SD卡的应答机制
如上,命令可以没有回应(无回应模式)可能SD卡在忙或者SD故障, 绝大多数命令是有回应的,首先主机给SD卡发一个命令 ,SD卡会给一个回应。对于命令格式,第一个位“0”表示开始,第二位表示是谁发的命令,若为“1”表示主机发送的命令,若为“0”表示SD卡发送的Response。
响应标记(token)根据内容不同具有四种格式,标记长度。长度为48位或136位。数据块的CRC算法采用16位的CCITT多项式。
SD卡初始化读写流程
SD卡的工作状态
所有主机和SD卡间的通信由主机控制。主机发送下述两类命令:
对卡而言也有两类操作:
- 卡识别模式—在重置(reset)后当主机查找总线上的额新卡时,处于卡识别模式。重置后SD卡将始终处于该模式,直到收到 SEND_RCA 命令(CMD3)。
- 数据传输模式—一旦卡的REC发布后,将进入数据传输模式。主机一旦识别了所有总线上的卡后,将进入数据传输模式。
状态切换
SD模式下的初始化与卡识别
简析:首先开机,开机之后发送一个 CMD0(复位命令),0号命令不需要回应,然后发送 CMD8(请求发送接口状态命令),就是主机发送这个命令,请求SD卡返回一个接口状态。如果没有回应,则执行左侧的流程,有回应,执行右侧的流程。
先分析右侧有回应的,通过SD卡的回应的数据,可以判断是SD卡2.0的协议还是其他的?回复的数据是否有效?如果卡有效(工作电压等等都正常),继续往下 发送 ACMD41(应用型命令,要求访问的卡发送它的操作寄存器(OCR)的内容),如果卡返回 busy ,则继续循环请求,直至卡回复 Ready,并针对回复的数据解析,如果其中 CCS = 1,则代表是一个高容量的卡,CCS = 1,则代表是一个标准容量的卡,然后发送 CMD2(要求所有卡发送 CID 号),卡回复之后,继续发送 CMD3(要求所有卡发布一个新的相对地址 RCA),至此,卡的初始化识别已完成,后面会进入传输模式。
传输模式
简析:卡识别模式最后一步的 CMD3 发完之后就进入了 数据传输模式,进入这个模式的第一个状态是 Stand by State(旁置),大概是暂时什么都不操作,等待命令,如果在这个状态下发了一个 CMD7(选中卡的状态,再发一次会返回不选中状态),SD卡会自动跳到 Transfer State (传输状态),进入传输状态之后,可以通过其他一些命令(如上图所示)进入 Sending Data State(发送数据)或者Recevie Date State(接收数据),通过 CMD12 可以将 SD卡从 发送状态返回到传输状态。当在接收数据状态下收到 CMD12,会先终止 SD卡的接收状态,这是接收的数据是临时存放在 “Buff”缓冲区(RAM),这个区域数据掉电会丢失,所以需要通过 Programming State 将 接收的数据另存到 Nand Flash或者寄存器中去。 (为什么先用到 RAM缓冲区?因为接收数据速度快,先接收主机传送的数据,然后慢慢另存),数据另存完,会返回 传输状态。在这整个过程中,如果接收到 CMD0命令,SD卡会强行退出传输模式,回到最原始的非激活状态。
SPI模式下的SD操作流程
对 SD卡的基本读写操作命令有:数据块读命令 READ_BLOCK(CMD17)、多数据块读命令READ_MULTIPLE_BLOCK(CMD18)和 数据块写命令 WRITE_BLOCK(CMD24)、多数据块写命令 WRITE_MULTIPLE_BLOCK(CMD25)。
因为我们使用的是SPI模式,所以先得让SD卡进入SPI模式。方法如下,在SD卡收到复位命令(CMD0)时,CS为有效电平(低电平)则SPI模式被启用。
在发送CMD0之前,要发送大于74个时钟脉冲,这是因为SD卡内部有个供电电压上升时间,而且还需要 SD卡同步。
在卡初 cc,CLK时钟最大不能超过 400KHz。
SPI模式
初始化步骤
SD卡的典型初始化过程如下:
1、初始化与SD卡连接的硬件条件(MCU的SPI配置、IO配置);
2、上电延时(>74个CLK);
3、复位卡(CMD0),进入IDLE状态;
4、发送CMD8,检测是否支持2.0协议;
5、根据不同协议检查SD卡(命令包括:CMD55、CMD41、CMD58和CMD1等);
6、取消片选,多发8个CLK,结束初始化。
读取步骤
SD卡读取数据,这里通过CMD17来实现,具体过程如下:
1、发送 CMD17;(告诉要读取的地址)
2、接收卡响应R1;
3、接收数据起始令牌 0XFE;(起始令牌表示数据的开始,可以丢掉,令牌之后就是真实的数据)
4、接收数据;
5、接收2个字节的 CRC,如果不使用 CRC,这两个字节在读取后可以丢掉。
6、禁止片选之后,多发8个CLK;
写操作步骤
1、发送 CMD24;
2、接收卡响应R1;
3、发送写数据起始令牌 0XFE;
4、发送数据;
5、发送2个字节的 伪CRC;
6、禁止片选之后,多发8个CLK;