怎么操作SD卡——从底层到FAT文件系统

文章详细介绍了STM32通过SDIO接口与SD卡进行通信的原理,包括SD卡的物理结构、SDIO命令类型、响应机制以及操作模式。此外,还讨论了SD卡的底层操作,如初始化和数据读写,并提到了如何挂载FAT32文件系统,强调了分层操作的思想在程序移植和文件系统管理中的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:本文章部分代码参考自野火的例程

有纰漏请指出,转载请说明。

学习交流请发邮件 1280253714@qq.com

程序源码在这里

1 SD卡是什么

1.1 SDIO简介

STM32通过SDIO与SD 卡 (Secure Digital Memory Card)进行通信

用了SDIO接口的,一类是如今很少用的MMC卡,一类是专为轻薄笔记本硬盘设计的硬盘高速通讯 的CE-ATA ,用得比较多的是SDIO传输的外设(WiFi、GPS)和SD存储卡,本篇主要讲解SD存储卡。

STM32F10x 系列 控制器只支持 SD 卡规范版本 2.0,即只支持标准容量 SD 和高容量 SDHC 标准卡 ,故支持的最高卡容量是 32GB 。

1.2 SD卡的物理结构

一张SD卡包括有存储单元、存储单元接口、电源检测、卡及接口控制器和接口驱动器5个部分

1.3 SDIO的命令

SD卡总线,其中1根CMD命令线,4根DATA数据线。

STM32通过SDIO外设发送命令到SD卡,SD卡响应并执行相应操作(读、写、块擦除等),接着STM32发送命令查询SD卡当前状态,若SD卡忙则继续等待。(如:SD卡发送块擦除命令,SD卡收到后响应,并执行块擦除,之后STM32轮询SD卡状态,直到SD卡擦除完方可执行下一操作)

SD命令有4种类型:

无响应广播命令(bc),发送到所有卡,不返回任务响应;

带响应广播命令(bcr),发送到所有卡,同时接收来自所有卡响应;

寻址命令(ac),发送到选定卡,DAT线无数据传输;

寻址数据传输命令(adtc),发送到选定卡,DAT线有数据传输。

另外,SD卡主机模块系统旨在为各种应用程序类型提供一个标准接口。在此环境中,需要有特定的客户/应用程序功能。为实现这些功能,在标准中定义了两种类型的通用命令:特定应用命令(ACMD)和常规命令(GEN_CMD)。要使用SD卡制造商特定的ACMD命令如ACMD6,需要在发送该命令之前发送CMD55命令,告知SD卡接下来的命令为特定应用命令。CMD55命令只对紧接的第一个命令有效,SD卡如果检测到CMD55之后的第一条命令为ACMD则执行其特定应用功能,如果检测发现不是ACMD命令,则执行标准命令。

讲人话就是:SD命令有64个通用命令CMD,厂商还制定了若干特定应用命令ACMD,要发ACMD前先发CMD55。

感受一下就好,知道是怎么一回事

1.4 SD卡的响应

响应由SD卡向主机发出,部分命令要求SD卡作出响应,这些响应多用于反馈SD卡的状态。基本特性如下:

  • SDIO总共有7个响应类型(代号:R1~R7),其中SD卡没有R4、R5类型响应。特定的命令对应有特定的响应类型,比如当主机发送CMD3命令时,可以得到响应R6。

  • 与命令一样,SD卡的响应也是通过CMD线连续传输的。

  • 根据响应内容大小可以分为短响应和长响应。短响应是48bit长度,只有R2类型是长响应,其长度为136bit。

SD卡响应时,可能发送CID、CSD、OCR、RCA寄存器中的值,通过CMD线发给STM32,存储在STM32的SDIO_RESP寄存器中,需要查询响应时,通过SDIO_GetResponse 函数获取寄存器的值。

1.5 SD卡的操作模式及切换

SD卡系统(包括主机和SD卡)定义了两种操作模式:卡识别模式和数据传输模式。在系统复位后,主机处于卡识别模式,寻找总线上可用的SDIO设备;同时,SD卡也处于卡识别模式,直到被主机识别到,即当SD卡接收到SEND_RCA(CMD3)命令后,SD卡就会进入数据传输模式,而主机在总线上所有卡被识别后也进入数据传输模式。

按照下图进行编程

1.6 SDIO接口

AHB总线接口:操作SDIO适配器模块中的寄存器,并产生中断和DMA请求信号。

SDIO适配器模块:实现所有MMC/SD/SD I/O卡的相关功能,如时钟的产生、命令和数据的传送。

1.7 SDIO的状态机

命令通道状态机(CPSM)

当SD卡处于某一状态时,SDIO适配器必然处于特定状态与之对应。STM32控制器以命令路径状态机(CPSM)来描述SDIO适配器状态变化,并加入了等待超时检测功能,以便退出永久等待的情况。

数据通道状态机(DPSM)

2 SD卡的底层操作

2.1 几个结构体

  • SDIO_InitTypeDef

SDIO初始化结构体成员用于设置SDIO工作环境参数,并由SDIO相应初始化配置函数或功能函数调用,这些参数将会被写入到SDIO相应的寄存器,达到配置SDIO工作环境的目的。

  • SDIO_CmdInitTypeDef

SDIO命令初始化结构体用于设置命令相关内容,比如命令号、命令参数、响应类型等等。

  • SDIO_DataInitTypeDef

SDIO数据初始化结构体用于配置数据发送和接收参数,比如传输超时、数据长度、传输模式等等。

2.2 SD_Init()函数

2.3 SD卡数据操作

SD 卡数据操作一般包括数据读取、数据写入以及存储区擦除。数据读取和写入都可以分为单块

操作和多块操作。

这几个函数(主要)及SD卡初始化函数,作为下文diskio.c的接口函数

3 SD卡挂载FAT32文件系统

3.1 如何移植FAT32文件系统,要修改哪些部分?

跟在FLASH上挂载FAT32文件系统一样,只需要底层提供给FatFs组件层一些数据操作的相关接口函数(放在bsp板级支持包里,即SD卡初始化、读状态、数据擦除、数据读写),然后修改diskio.c的具体内容,包括以下几个函数,以适应用户层对文件的操作。

diskio.c

3.2 分层操作的思想

这种思想很值得学习:应用编写的软件工程师只需关心对文件如何操作(创建、删除目录,打开、关闭、读写文件等等),将底层与应用层联系起来的中间层函数(驱动,hal硬件抽象层、bsp板级支持包)交给嵌入式软件工程师来处理。

这种分层操作的思想,在程序移植时,更为方便,可屏蔽不同硬件的底层逻辑。不管是FLASH还是SD卡,都可以通过这种方式来挂载FAT32文件系统,方便对文件进行操作。

在操作系统中、计算机网络中,这种分层操作的也用得很多,一句话,即“向下屏蔽差异,向上提供统一的东西”。

更简单地理解分层思想:

在更为底层的硬件与驱动,例如:A板子的LED灯为PA5,B板子的LED灯为PB0,那么,将A板驱动LED点亮的程序移植到B板时,只需将

#define LED1_GPIO_PORT GPIOA /* GPIO端口 */
#define LED1_GPIO_CLK RCC_APB2Periph_GPIOA/* GPIO端口时钟 */
#define LED1_GPIO_PINGPIO_Pin_5

改为

#define LED1_GPIO_PORT GPIOB /* GPIO端口 */
#define LED1_GPIO_CLK RCC_APB2Periph_GPIOB/* GPIO端口时钟 */
#define LED1_GPIO_PINGPIO_Pin_0

就可以了,点亮LED灯的相关函数无需更改。

3.3 应用层函数

C语言stdio.h包含的库函数

FAT32中ff.h的函数

3.4 发散联想

当我们在Windows上用鼠标双击文件时,具体的操作可能是用C#编写的桌面式应用程序通过操作系统调用了f_open函数,不得而知……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值