SD卡的初始化及基本应用

SD卡的初始化

上一篇文章我分享了一些关于SDIO接口的理解,通过SDIO接口,我们现在已经可以通过stm32与SD卡通信了。在通信之前,我们需要对SD卡进行初始化操作,对SD卡初始化需要通过我们前面说的CMD命令,SD卡接收到相应的CMD命令后,反馈相应的数据,我们便是通过这些反馈的数据对我们SD卡的类型,大小等进行判断,从而完成初始化。

这里上一张与SD卡参数有关的5个会反馈的寄存器:
在这里插入图片描述
其初始化的流程为:
①、发送CMD0命令,使SD卡进入Idle状态。
②、发送CMD8命令,改变VHS位,告诉SD卡主机供电范围。若响应正常,在发送CMD55命令,若响应正常,则可以区分出我们的卡是SD卡还是MMC卡。
③、若以上都响应正常,发送CMD55命令,响应正常后发送ACMD41命令,携带参数为供电电压范围和HCS位。也就是说我们对HCS位写1,然后判断返回的R3类型的响应(对应的位,第30位)是否也为1,若为1,则为大容量卡 SDHC 卡。
④、至此,我们已经区分好了卡的类型(MMC,SDHC,SDSC),然后根据响应数据判断SDIO->RESP1寄存器的上电位是否置1。若置1则表示上电完成。接下来发送指令获取SD卡对应的信息。
⑤、发送CMD2,反馈长响应,获取CID。
⑥、发送CMD3,用于设置卡的相对地址(RCA,必须为非0),对于SD卡,在收到CMD3后,将返回一个新的RCA给主机(卡发送RCA到主机),主机记录了新的RCA即为此时这张SD卡的相对地址。通过CMD3带参数(高16位用于RCA设置),实现RCA设置
⑦、发送CMD9和RCA,反馈长反应,获取CSD。从CSD寄存器,我们便可以直到SD卡的容量,扇区大小等十分重要的信息。
⑧、发送CMD7,带参数rca,使能SD卡。
⑨、SDIO_Clock_Set(clkdiv);//clkdiv = 0x00
通过这个语句设置频率为24MHz。公式看之前的SDIO接口文章。因为之前初始化过程,频率不得高于400KHz,所以现在调高速度。
⑩、SDIO->CLKCR|=WideMode;
#define SDIO_BusWide_4b ((uint32_t)0x00000800)
WideMode = SDIO_BusWide_4b;
通过CLKCR寄存器设置总线宽度为4bit。
也可以通过CMD55+ACMD6配置为4bit数据传输模式来设置。

最后设置SD卡的工作模式为查询模式即可,初始化就到这里!

SD卡读取数据流程

SD卡读取一个块流程

在这里插入图片描述
①、发送CMD16+设置数据长度为blksize,短响应。
②、发送CMD17+从addr地址出读取数据,短响应。
③、关闭总中断,判断当前SD卡工作模式。
④、如果是轮询模式,就等待SD卡的FIFO寄存器半满(8个字),然后把数据存进数组中,数组地址++,一次读8个字。直到SD卡的STA寄存器完成标志置位,结束读取。也就相当于从SD卡的一个地址,读取了blksize(一般我们设置512字节)大小的数据,把这些数据写进了我们自己定义的数组中。

SD卡读取多个块流程

在这里插入图片描述
①、开始流程都差不多,发送CMD16设置数据块大小,注意这里我们设置了数据长度,上面我们说了可以判断SD卡的STA寄存器完成标志是否置位,来判断传输是否完成,那么这里的置位与否,就是看数据长度(块大小 * 块数)。
②、发送CMD18+addr,addr指示我们要从什么地址开始读。
③、接收数据的流程和单块一样,我们只是改变了数据长度,从而改变了读取大小。数据长度可以通过这个函数来设置SDIO_DataConfig()。
④、接收完成后我们发送CMD12来结束数据块读取。

SD卡写入一个块流程

在这里插入图片描述
①、和读取有一点区别,我们设置好CMD16+数据块大小命令后,要先对SD卡进行查忙操作,也就是发送CMD13+RCA,根据反馈的数据我们判断卡是否繁忙,若繁忙则一直查询,直到一定时间(超时了就return呗)。
②、写入CMD24+addr,就可以往addr这个地址里面写入数据了。
③、原子的程序在这里做了很复杂的判断,简单说就是当剩余数据长度大于32字节,就很普通的往地址里写数据,写完8个字addr+32。若剩余数据长度小于32字节,则根据当前的SD卡的写入地址判断还剩几个字节,这样可以防止在循环写入数据时,超过数据长度导致报错。

SD卡写入多个块流程

我们直接上图吧,不多啰嗦了
在这里插入图片描述
预擦除是为了提高SD卡写入速度,(ACMD23+数据块个数)

至此,SD卡的读取我们算是介绍完了。需要注意的是,对SD卡进行读写操作时一定不能用局部数组来做,有很大概率导致内存叠加。所以我们最好使用一定的内存管理方法,去更好地来使用我们的SD卡。具体可以看我内存管理的博客,有很详细的介绍。
stm32内存管理及堆栈管理

我们还是感觉SD卡的操作过于麻烦,很多的文件又不好转换成纯16进制文件来供我们使用,所以我下面打算给大家介绍一下FATfs文件管理。

发布了12 篇原创文章 · 获赞 11 · 访问量 3822

猜你喜欢

转载自blog.csdn.net/su_fei_ma_su/article/details/104333776