SD卡分为SDIO模式与SPI模式,SDIO模式使用SD总线协议,使用4根数据线进行数据传输,SPI使用1收1发2根数据线数据传输,理论上SDIO模式会比SPI模式速度快4倍,但SDIO模式还牵扯到CRC校验位的计算,所以:如果使用CPU有限制的话不用太纠结选取哪个模式。这里只对SPI模式进行说明:
注:SD卡默认处于SD模式
一、接口连线:
接口连线给3张图吧,很直观:
二、SD卡命令说明
SD卡命令有6个字节构成:
字节1:指令标号,即 0----cmd0 注:该字节第7位始终为1,即每一个命令都需 |=0x40;
字节2,3,4,5:指令内容
字节6:指令校验位crc,spi模式不对其进行校验,可发送任意数值,一般选取0xff,但必须发送,不可省略
指令后为正确应答数据
CMD0: 0x40,0x00,0x00,0x00,0x00,0x95-------0x01
CMD1: 0x41,0x00,0x00,0x00,0x00,0x01-------0x00
MMC卡使用CMD1命令初始化
CMD8: 0x48,0x00,0x00,0x01,0xAA,0x87-------0x01(SD2.0)
判断SD卡的版本,同时读取后续应答获知SD卡工作电压,一般为0x01aa,
即:支持2.7~3.6v工作电压
CMD16 0x50,0x00,0x00,0x02,0x00,0x01
设置扇区大小为512字节,同时验证初始化是否成功
注:设置时不可小于512字节,且为512整倍数
CMD55 0x77,0x00,0x00,0x00,0x00,0x01
用于说明后一条指令为ACMD,即:CMD55+ACMD41配合进行使用
ACMD41(SD2.0) 0x69,0x40,0x00,0x00,0x00,0x01
用于检测SD卡是否初始化完成,针对2.0的SD卡
ACMD41(SD2.1) 0x69,0x00,0x00,0x00,0x00,0x01
用于检测SD卡是否初始化完成,针对1.0的SD卡
CMD58 0x7A,0x00,0x00,0x00,0x00,0x01
用于鉴别SD2.0卡类型 SDHC或普通SD卡
区别:扇区地址的寻址方式不同
SDHC为扇区块进行寻址
普通SD卡位字节地址寻址
注:MMC卡使用CMD1来进行初始化,而SD卡则使用CMD55+ACMD41来进行初始化
三、SD卡初始化步骤
- 设置SPI时钟为低速0~400khz-------------SD卡初始化只能在低速模式下进行
- 发送至少74个周期的时钟信号-------------建议适当多发送一些
- 发送SD卡命令CMD0-------------------------使SD卡切换至spi模式,进入IDLE状态
- 发送CMD8(SD2.0)----------------------------针对SD2.0进行鉴别 同时读取后续4个字节返回值,判断其是否支持工作电压(例如:2.7~3.6v支持则为0x01aa)
- 发送CMD55+ACMD41(SD2.0)-----检测初始化是否完成
- 发送CMD58------------------------------对SD2.0版本进一步确认SD卡型号
- 发送CMD55+ACMD41(SD1.0)-------------检测返回值进行判断为SD1.0或MMC卡
- 发送CMD55+ACMD41(SD1.0)------检测初始化是否完成
- 发送CMD1(MMC)------------------------------针对MMC卡进行初始化
- 发送CMD16--------------------------------------设置SD卡扇区大小(默认为512字节)
- 设置SPI时钟为高速,最大为25Mhz--------初始化完成
四、补充说明
关于CSD、OCR、CID寄存器的说明可自行百度,或参考SD协议。
不同型号SD卡可能略有不同,可调整各步骤执行次数可解决绝大部分问题(不知名SD卡除外,可能需要更多次数的指令发送)
以上所使用的命令并非SD卡全部命令,若有需要,请参考协议。