【ESP-IDF】ESP32S3用SPI读写 MicroSD/TF卡(一)SD卡初始化

        如何使用外部储存、如何使用标准文件系统读写信息,是比较大的课题,我想用几篇文章的幅度详细介绍自己写驱动程序、移植文件系统库,在不依赖ESP官方库的情况下完成ESP32S3对SD卡的控制,此过程解剖了SD卡操作和文件系统操作的核心。

        这是系列文章,链接如下:

【ESP-IDF】ESP32S3用SPI读写 MicroSD/TF卡(二)读写正文数据_spi读写sd卡驱动需要自己写吗-CSDN博客

       【ESP-IDF】ESP32S3用SPI读写 MicroSD/TF卡(三)移植FATFS文件系统-CSDN博客

【ESP-IDF】ESP32S3用SPI读写 MicroSD/TF卡(四-用ESPIDF官方库)_esp32 tf卡引脚-CSDN博客        此篇先解决物理驱动层,就是如何用SPI协议操控SD卡的寄存器。重点与硬件和SD卡数据手册交涉。

        我用 ESPIDF自带的sdspi库失败,失败定位在SD卡初始化过程,发送多次ACMD41仍无法接收SD卡0x00回复,超时(主程序返回0x107错误),初始化失败。于是自己写了SD卡SPI模式的通讯协议查看究竟。

一、硬件

        SD卡、MicroSD、TF卡都是用一样的代码一样的协议。MMC卡的协议流程略有不同。SD卡里面还有细分为超大容量SDXC、大容量SDHC和小容量SDSC(2GB以下)三种,接线一样,代码上略有区别,而这些区别挺致命的。        

图1:通讯失败的MicrSD卡模块
图2:通讯成功的Microsd卡模块

         一开始用图1的MicroSD卡模块,有弹簧自锁的,还有3.3v稳压器,电路设计比图二稳当,但到了ACMD41初始化时尝试5000次都总是失败,CMD0和CMD8倒是正常。换过其他sd卡试过,耗了我好多天后,终于下单换了图二的模块,简陋一点,但原代码测试ACMD41就通过了,R1返回0x00。

        我用这种256MB的便宜小卡,属于SDSC。 

        SD卡结构分为控制寄存器和储存单元,我们的指令就是操作控制寄存器。

二、SD卡手册关于指令、参数、response的说明

2.1 指令和参数

#define pin_CS 9
#define pin_MOSI 10
#define pin_MISO 12
#define pin_CLK 11

/*CMD type,包含从命令到CRC共48bits*/
#define CMD0 	0x400000000095
#define CMD1	0x4100000000FF
#define CMD8 	0x48000001AA87
#define CMD55 	0x770000000065
#define ACMD41	0x694000000077  
#define CMD58	0x7A00000000FF
#define CMD10	0x4A00000000FF  //接收CID信息
#define CMD12	0x4C00000000FF	//中止读写
#define CMD17	0x5100000000FF  //读1个block 512bytes
#define CMD18   0x5200000000FF  //读多个blocks
#define CMD24   0x5800000000FF  //写1block
#define CMD25   0x5900000000FF	//写多blocks
#define CMD13	0x4D00000000FF	//写存储后查看卡status,R2响应
#define CMD32	0x6000000000FF	//erase start addr
#define CMD33	0x6100000000FF	//erase end addr
#define CMD38	0x6600000000FF	//erase all

/*response type, the figure indicates length in bytes*/
typedef enum _response_t{R1=1,R7=5,R2=17,R3=5}response_t;

        以上就是SD卡常用操作指令,而本篇需要用到的指令到CMD58为止,就能完成SD卡物理初始化过程,指令按出场顺序排好了。       

        说一下指令的数值构成。CMD0的数值就是0,CMD8就是8,CMD10就是十进制的10。以CMD10为例,10转变成十六进制就是0x0A,加上0x40就是0x4A了。所有指令都是从0x40开始加上去,看CMD0就知道了。

        ACMD41也是跟普通CMD命令一样计算。十进制的41就是十六进制的0x29,加到0x40上等于0x69。ACMD41的第三位可以是4也可以是0,小容量卡用0也可,大容量卡用4,其实无论你用什么都不影响SD卡回复你的消息。

        注意主机发出的所有指令,SD卡都会在后面回复一个response。

2.2 CRC计算

        从CMD0至ACMD41都要强调CRC计算准确,ACMD41之后的指令随意填个CRC就可,SD卡手册这样说的。因为SPI模式下,SD卡不检查CRC。但是ACMD41之前卡片都没完成初始化,SD卡不清楚主机采用哪种方式来沟通,因此要正确的CRC。        

        计算CRC的工具在这个网址:

CRC(循环冗余校验)在线计算_ip33.com

        command用CRC7的模式,计算工具使用过程如下:

        我这是用CMD55、0x77000000006

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值