SDIO—SD 卡读写测试
SD 卡 (Secure Digital Memory Card) 在我们生活中已经非常普遍了,控制器对 SD 卡进行读写通信操作一般有两种通信接口可选,一种是 SPI 接口,另外一种就是 SDIO 接口。 SDIO 全称是安全数字输入/输出接口,多媒体卡 (MMC)、 SD 卡、 SD I/O 卡都有 SDIO 接口。 STM32F10x 系列控制器有一个 SDIO 主机接口,它可以与 MMC
1.SDIO 简介
SD 卡 (Secure Digital Memory Card) 在我们生活中已经非常普遍了,控制器对 SD 卡进行读写通信操作一般有两种通信接口可选,一种是 SPI 接口,另外一种就是 SDIO 接口。 SDIO 全称是安全数字输入/输出接口,多媒体卡 (MMC)、 SD 卡、 SD I/O 卡都有 SDIO 接口。 STM32F10x 系列控制器有一个 SDIO 主机接口,它可以与 MMC 卡、 SD 卡、 SD I/O 卡以及 CE-ATA 设备进行数据传输。MMC 卡可以说是 SD 卡的前身,现阶段已经用得很少。 SD I/O 卡本身不是用于存储的卡,它是指利用 SDIO 传输协议的一种外设。比如 Wi-Fi Card,它主要是提供 Wi-Fi 功能,有些 Wi-Fi 模块是使用串口或者 SPI 接口进行通信的,但 Wi-Fi SDIO Card 是使用 SDIO 接口进行通信的。并且一般设计 SD I/O 卡是可以插入到 SD 的插槽。 CE-ATA 是专为轻薄笔记本硬盘设计的硬盘高速通讯接口。
多媒体卡协会网站www.mmca.org中提供了有 MMCA 技术委员会发布的多媒体卡系统规范。
SD 卡协会网站 www.sdcard.org 中提供了 SD 存储卡和 SDIO 卡系统规范。
CE-ATA 工作组网站www.ce-ata.org中提供了 CE_ATA 系统规范。
随之科技发展, SD 卡容量需求越来越大, SD 卡发展到现在也是有几个版本的,关于 SDIO 接口
的设备整体概括见下图:

关于 SD 卡和 SD I/O 部分内容可以在 SD 协会网站获取到详细的介绍,比如各种 SD 卡尺寸规则、读写速度标示方法、应用扩展等等信息。
本内容针对 SD 卡使用讲解,对于其他类型卡的应用可以参考相关系统规范实现,所以对于控制器中针对其他类型卡的内容可能在本章中简单提及或者被忽略,本章内容不区分 SDIO 和 SD卡这两个概念。即使目前 SD 协议提供的 SD 卡规范版本最新是 4.01 版本,但 STM32F10x 系列控制器只支持 SD 卡规范版本 2.0,即只支持标准容量 SD 和高容量 SDHC 标准卡,不支持超大容量 SDXC 标准卡,所以可以支持的最高卡容量是 32GB。
2. SD 卡物理结构
一张 SD 卡包括有存储单元、存储单元接口、电源检测、卡及接口控制器和接口驱动器 5 个部分,见图 35‑2。存储单元是存储数据部件,存储单元通过存储单元接口与卡控制单元进行数据传输;电源检测单元保证 SD 卡工作在合适的电压下,如出现掉电或上状态时,它会使控制单元和存储单元接口复位;卡及接口控制单元控制 SD 卡的运行状态,它包括有 8 个寄存器;接口驱动器控制 SD 卡引脚的输入输出。

SD 卡总共有 8 个寄存器,用于设定或表示 SD 卡信息,参考表 35‑1。这些寄存器只能通过对应的命令访问,对 SD 卡进行控制操作并不是像操作控制器 GPIO 相关寄存器那样一次读写一个寄存器的,它是通过命令来控制, SDIO 定义了 64 个命令,每个命令都有特殊意义,可以实现某一特定功能, SD 卡接收到命令后,根据命令要求对 SD 卡内部寄存器进行修改,程序控制中只需要发送组合命令就可以实现 SD 卡的控制以及读写操作。

每个寄存器位的含义可以参考 SD 简易规格文件《Physical Layer Simplified Specification V2.0》第 5章内容。
3. SDIO 总线
3.1 总线拓扑
SD 卡一般都支持 SDIO 和 SPI 这两种接口,本章内容只介绍 SDIO 接口操作方式,如果需要使用
SPI 操作方式可以参考 SPI 相关章节。另外, STM32F10x 系列控制器的 SDIO 是不支持 SPI 通信模式的,如果需要用到 SPI 通信只能使用 SPI 外设。
SD 卡总线拓扑参考图 35‑3。虽然可以共用总线,但不推荐多卡槽共用总线信号,要求一个单独
SD 总线应该连接一个单独的 SD 卡。
SD 卡使用 9-pin 接口通信,其中 3 根电源线、 1 根时钟线、 1 根命令线和 4 根数据线,具体说明如下:
• CLK: 时钟线,由 SDIO 主机产生,即由 STM32 控制器输出;
• CMD: 命令控制线, SDIO 主机通过该线发送命令控制 SD 卡,如果命令要求 SD 卡提供应答 (响应), SD 卡也是通过该线传输应答信息;
• D0-3: 数据线,传输读写数据; SD 卡可将 D0 拉低表示忙状态;
• VDD、 VSS1、 VSS2: 电源和地信号。
在之前的 I2C 以及 SPI 章节都有详细讲解了对应的通信时序,实际上, SDIO 的通信时序简单许多, SDIO 不管是从主机控制器向 SD 卡传输,还是 SD 卡向主机控制器传输都只以 CLK 时钟线的上升沿为有效。 SD 卡操作过程会使用两种不同频率的时钟同步数据,一个是识别卡阶段时钟频率 FOD,最高为 400kHz,另外一个是数据传输模式下时钟频率 FPP,默认最高为 25MHz,如果通过相关寄存器配置使 SDIO 工作在高速模式,此时数据传输模式最高频率为 50MHz。
对于 STM32 控制器只有一个 SDIO 主机,所以只能连接一个 SDIO 设备,开发板上集成了一个Micro SD 卡槽和 SDIO 接口的 WiFi 模块,要求只能使用其中一个设备。 SDIO 接口的 WiFi 模块一般集成有使能线,如果需要用到 SD 卡需要先控制该使能线禁用 WiFi 模块。
3.2 总线协议
SD 总线通信是基于命令和数据传输的。通讯由一个起始位 (“0” ),由一个停止位 (“1” ) 终止。SD 通信一般是主机发送一个命令 (Command),从设备在接收到命令后作出响应 (Response),如有需要会有数据 (Data) 传输参与。
SD 总线的基本交互是命令与响应交互,见图 4。

SD 数据是以块 (Black) 形式传输的, SDHC 卡数据块长度一般为 512 字节,数据可以从主机到卡,也可以是从卡到主机。数据块需要 CRC 位来保证数据传输成功。 CRC 位由 SD 卡系统硬件生成。STM32 控制器可以控制使用单线或 4 线传输,本开发板设计使用 4 线传输。 图5 为主机向 SD卡写入数据块操作示意。

图5 多块写入操作
SD 数据传输支持单块和多块读写,它们分别对应不同的操作命令,多块写入还需要使用命令来停止整个写入操作。数据写入前需要检测 SD 卡忙状态,因为 SD 卡在接收到数据后编程到存储区过程需要一定操作时间。 SD 卡忙状态通过把 D0 线拉低表示。
数据块读操作与之类似,只是无需忙状态检测。
使用 4 数据线传输时,每次传输 4bit 数据,每根数据线都必须有起始位、终止位以及 CRC 位,CRC 位每根数据线都要分别检查,并把检查结果汇总然后在数据传输完后通过 D0 线反馈给主机。
SD 卡数据包有两种格式,一种是常规数据 (8bit 宽),它先发低字节再发高字节,而每个字节则是先发高位再发低位, 4 线传输示意如图 6。
图6 8 位宽数据包传输
4 线同步发送,每根线发送一个字节的其中两个位,数据位在四线顺序排列发送, DAT3 数据线发较高位, DAT0 数据线发较低位。
另外一种数据包发送格式是宽位数据包格式,对 SD 卡而言宽位数据包发送方式是针对 SD 卡SSR(SD 状态) 寄存器内容发送的, SSR 寄存器总共有 512bit,在主机发出 ACMD13 命令后 SD卡将 SSR 寄存器内容通过 DAT 线发送给主机。宽位数据包格式示意见图 7。

图7 宽位数据包传输
3.3 命令
SD 命令由主机发出,以广播命令和寻址命令为例,广播命令是针对与 SD 主机总线连接的所有从设备发送的,寻址命令是指定某个地址设备进行命令传输。
3.3.1 命令格式
SD 命令格式固定为 48bit,都是通过 CMD 线连续传输的(数据线不参与),见图8。

图 8 SD 命令格式
SD 命令的组成如下:
• 起始位和终止位:命令的主体包含在起始位与终止位之间,它们都只包含一个数据位,起始位为 0,终止位为 1。
• 传输标志:用于区分传输方向,该位为 1 时表示命令,方向为主机传输到 SD 卡,该位为 0时表示响应,方向为 SD 卡传输到主机。
命令主体内容包括命令、地址信息/参数和 CRC 校验三个部分。
• 命令号:它固定占用 6bit,所以总共有 64 个命令 (代号: CMD0~CMD63),每个命令都有特定的用途,部分命令不适用于 SD 卡操作,只是专门用于 MMC 卡或者 SD I/O 卡。
• 地址/参数:每个命令有 32bit 地址信息/参数用于命令附加内容,例如,广播命令没有地址信息,这 32bit 用于指定参数,而寻址命令这 32bit 用于指定目标 SD 卡的地址。
• CRC7 校验:长度为 7bit 的校验位用于验证命令传输内容正确性,如果发生外部干扰导致传输数据个别位状态改变将导致校准失败,也意味着命令传输失败, SD 卡不执行命令。
34.3.3.2 命令类型
SD 命令有 4 种类型:
• 无响应广播命令 (bc),发送到所有卡,不返回任务响应;
• 带响应广播命令 (bcr),发送到所有卡,同时接收来自所有卡响应;
• 寻址命令 (ac),发送到选定卡, DAT 线无数据传输;
• 寻址数据传输命令 (adtc),发送到选定卡, DAT 线有数据传输。
另外, SD 卡主机模块系统旨在为各种应用程序类型提供一个标准接口。在此环境中,需要有特定的客户/应用程序功能。为实现这些功能,在标准中定义了两种类型的通用命令:特定应用命令 (ACMD) 和常规命令 (GEN_CMD)。要使用 SD 卡制造商特定的 ACMD 命令如 ACMD6,需要在发送该命令之前无发送 CMD55 命令,告知 SD 卡接下来的命令为特定应用命令。 CMD55 命令只对紧接的第一个命令有效, SD 卡如果检测到 CMD55 之后的第一条命令为 ACMD 则执行其特定应用功能,如果检测发现不是 ACMD 命令,则执行标准命令。
3.3.3 命令描述
SD 卡系统的命令被分为多个类,每个类支持一种“卡的功能设置”。表 35‑2 列举了 SD 卡部分命令信息,更多详细信息可以参考 SD 简易规格文件说明,表中填充位和保留位都必须被设置为 0。虽然没有必须完全记住每个命令详细信息,但越熟悉命令对后面编程理解非常有帮助。
![]()






3.4 响应
响应由 SD 卡向主机发出,部分命令要求 SD 卡作出响应,这些响应多用于反馈 SD 卡的状态。SDIO 总共有 7 个响应类型 (代号: R1~R7),其中 SD 卡没有 R4、 R5 类型响应。特定的命令对应有特定的响应类型,比如当主机发送 CMD3 命令时,可以得到响应 R6。与命令一样, SD 卡的响应也是通过 CMD 线连续传输的。根据响应内容大小可以分为短响应和长响应。短响应是 48bit长度,只有 R2 类型是长响应,其长度为 136bit。各个类型响应具体情况如表 35‑3。
除了 R3 类型之外,其他响应都使用 CRC7 校验来校验,对于 R2 类型是使用 CID 和 CSD 寄存器内部 CRC7。
表 3 SD 卡响应类型

4. SD 卡的操作模式及切换
4.1 SD 卡的操作模式
SD 卡有多个版本, STM32 控制器目前最高支持《Physical Layer Simplified Specification V2.0》定义的 SD 卡, STM32 控制器对 SD 卡进行数据读写之前需要识别卡的种类: V1.0 标准卡、 V2.0 标准卡、 V2.0 高容量卡或者不被识别卡。
SD 卡系统 (包括主机和 SD 卡) 定义了两种操作模式:卡识别模式和数据传输模式。在系统复位后,主机处于卡识别模式,寻找总线上可用的 SDIO 设备;同时, SD 卡也处于卡识别模式,直到被主机识别到,即当 SD 卡接收到 SEND_RCA(CMD3) 命令后, SD 卡就会进入数据传输式,
而主机在总线上所有卡被识别后也进入数据传输模式。在每个操作模式下, SD 卡都有几种状态,参考表4,通过命令控制实现卡状态的切换。
表4 SD 卡状态与操作模式

4.2 卡识别模式
在卡识别模式下,主机会复位所有处于“卡识别模式”的 SD 卡,确认其工作电压范围,识别 SD卡类型,并且获取 SD 卡的相对地址 (卡相对地址较短,便于寻址)。在卡识别过程中,要求 SD 卡工作在识别时钟频率 FOD 的状态下。卡识别模式下 SD 卡状态转换如图 35_9。

图 9 卡识别模式状态转换图
主 机 上 电 后, 所 有 卡 处 于 空 闲 状 态, 包 括 当 前 处 于 无 效 状 态 的 卡。 主 机 也可 以 发 送GO_IDLE_STATE(CMD0) 让所有卡软复位从而进入空闲状态,但当前处于无效状态的卡并不会复位。
主机在开始与卡通信前,需要先确定双方在互相支持的电压范围内。 SD 卡有一个电压支持范围,主机当前电压必须在该范围可能才能与卡正常通信。 SEND_IF_COND(CMD8) 命令就是用于验证卡接口操作条件的 (主要是电压支持)。卡会根据命令的参数来检测操作条件匹配性,如果卡支持主机电压就产生响应,否则不响应。而主机则根据响应内容确定卡的电压匹配性。 CMD8 是 SD卡标准 V2.0 版本才有的新命令,所以如果主机有接收到响应,可以判断卡为 V2.0 或更高版本SD 卡。
SD_SEND_OP_COND(ACMD41) 命令可以识别或拒绝不匹配它的电压范围的卡。 ACMD41 命令的 VDD 电压参数用于设置主机支持电压范围,卡响应会返回卡支持的电压范围。对于对CMD8有响应的卡,把 ACMD41 命令的 HCS 位设置为 1,可以测试卡的容量类型,如果卡响应的CCS 位为 1 说明为高容量 SD 卡,否则为标准卡。卡在响应 ACMD41 之后进入准备状态,不响应 ACMD41的卡为不可用卡,进入无效状态。 ACMD41 是应用特定命令,发送该命令之前必须先发 CMD55。
ALL_SEND_CID(CMD2) 用来控制所有卡返回它们的卡识别号 (CID),处于准备状态的卡在发送CID 之后就进入识别状态。之后主机就发送 SEND_RELATIVE_ADDR(CMD3) 命令,让卡自己推荐一个相对地址 (RCA) 并响应命令。这个 RCA 是 16bit 地址,而 CID 是 128bit 地址,使用 RCA简化通信。卡在接收到 CMD3 并发出响应后就进入数据传输模式,并处于待机状态,主机在获取所有卡 RCA 之后也进入数据传输模式。
4.3 数据传输模式
只有 SD 卡系统处于数据传输模式下才可以进行数据读写操作。数据传输模式下可以将主机 SD时钟频率设置为 FPP,默认最高为 25MHz,频率切换可以通过 CMD4 命令来实现。数据传输模式下, SD 卡状态转换过程见图10。

图10 数据传输模式卡状态转换
CMD7 用来选定和取消指定的卡,卡在待机状态下还不能进行数据通信,因为总线上可能有多个卡都是出于待机状态,必须选择一个 RCA 地址目标卡使其进入传输状态才可以进行数据通信。
同时通过 CMD7 命令也可以让已经被选择的目标卡返回到待机状态。
数据传输模式下的数据通信都是主机和目标卡之间通过寻址命令点对点进行的。卡处于传输状态下可以使用表 35‑2 中面向块的读写以及擦除命令对卡进行数据读写、擦除。 CMD12 可以断
正在进行的数据通信,让卡返回到传输状态。 CMD0 和 CMD15 会中止任何数据编程操作,返回卡识别模式,这可能导致卡数据被损坏。
5. STM32 的 SDIO 功能框图
STM32 控制器有一个 SDIO,由两部分组成: SDIO 适配器和 AHB 接口,见图11。 SDIO 适配器提供 SDIO 主机功能,可以提供 SD 时钟、发送命令和进行数据传输。 AHB 接口用于控制器访问 SDIO 适配器寄存器并且可以产生中断和 DMA 请求信号。

图11 SDIO 功能框图
SDIO 使用两个时钟信号,一个是 SDIO 适配器时钟 (SDIOCLK=HCLK=72MHz),另外一个是 AHB总线时钟的二分频 (HCLK/2,一般为 36MHz)。 适配器寄存器和 FIFO 使用 AHB 总线一侧的时钟(HCLK/2),控制单元、命令通道和数据通道使用 SDIO 适配器一侧的时钟 (SDIOCLK)。SDIO_CK 是 SDIO 接口与 SD 卡用于同步的时钟信号。它使用 SDIOCLK 作为 SDIO_CK 的时来源,可以通过设置 BYPASS 模式直接得到,这时 SDIO_CK = SDIOCLK=HCLK。若禁止BYPASS 模式,可以通过配置时钟寄存器的 CLKDIV 位控制分频因子,即 SDIO_CK=SDIOCLK/(2+CLKDIV)= HCLK/(2+CLKDIV)。配置时钟时要注意, SD 卡普遍要求 SDIO_CK 时钟频率不能超过 25MHz。
STM32 控制器的 SDIO 是针对 MMC 卡和 SD 卡的主设备,所以预留有 8 根数据线,对于 SD 卡最多用四根数据线。
1SDIO 适配器是 SD 卡系统主机部分,是 STM32 控制器与 SD 卡数据通信中间设备。 SDIO适配器由五个单元组成,分别是控制单元、命令路径单元、数据路径单元、寄存器单元以及 FIFO,见图 12。

图 12 SDIO 适配器框图
5.1 控制单元
控制单元包含电源管理和时钟管理功能,结构如图 35‑13。电源管理部件会在系统断电和上电阶段禁止 SD 卡总线输出信号。时钟管理部件控制 CLK 线时钟信号生成。一般使用 SDIOCLK 分频得到。

图 13 SDIO 适配器控制单元
5.2 命令路径
命令路径控制命令发送,并接收卡的响应,结构见图14。

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

图15 CPSM 状态机描述图
5.3 数据路径
数据路径部件负责与 SD 卡相互数据传输,内部结构见图16。

图 16 SDIO 适配器数据路径
SD 卡系统数据传输状态转换参考图 10, SDIO 适配器以数据路径状态机 (DPSM) 来描述SDIO适配器状态变化情况。并加入了等待超时检测功能,以便退出永久等待情况。发送数据时,DPSM处于等待发送 (Wait_S) 状态,如果数据 FIFO 不为空, DPSM 变成发送状态并且数据路径部件启动向卡发送数据。接收数据时, DPSM 处于等待接收状态,当 DPSM 收到起始位时变成接收状态,并且数据路径部件开始从卡接收数据。 DPSM 状态机描述见图17。

图17 DPSM 状态机描述图
5.4 数据 FIFO
数据 FIFO(先进先出) 部件是一个数据缓冲器,带发送和接收单元。控制器的 FIFO 包含宽度为32bit、深度为 32 字的数据缓冲器和发送/接收逻辑。其中 SDIO 状态寄存器 (SDIO_STA) 的TXACT位用于指示当前正在发送数据, RXACT 位指示当前正在接收数据,这两个位不可能同时为 1。
• 当 TXACT 为 1 时,可以通过 AHB 接口将数据写入到传输 FIFO。
• 当 RXACT 为 1 时,接收 FIFO 存放从数据路径部件接收到的数据。
根据 FIFO 空或满状态会把 SDIO_STA 寄存器位值 1,并可以产生中断和 DMA 请求。
5.5 适配器寄存器
适配器寄存器包含了控制 SDIO 外设的各种控制寄存器及状态寄存器,内容较多,可以通过 SDIO提供的各种结构体来了解,这些寄存器的功能都被整合到了结构体或 STM32HAL 库之中。
6. SDIO 初始化结构体
HAL 库 函 数 对 SDIO 外 设 建 立 了 三 个 初 始 化 结 构 体, 分 别 为 SDIO 初 始 化 结 构 体SDIO_InitTypeDef、 SDIO 命令初始化结构体 SDIO_CmdInitTypeDef 和 SDIO 数据初始化结构体SDIO_DataInitTypeDef。这些结构体成员用于设置 SDIO 工作环境参数,并由 SDIO 相应初始化配置函数或功能函数调用,这些参数将会被写入到 SDIO 相应的寄存器,达到配置 SDIO 工作环境的目的。
初始化结构体和初始化库函数配合使用是 HAL 库精髓所在,理解了初始化结构体每个成员意义基本上就可以对该外设运用自如了。初始化结构体定义在 stm32f1xx_hal_sd.h 文件中,初始化库函数定义在 stm32f1xx_hal_sdio.c 文件中,编程时我们可以结合这两个文件内注释使用。SDIO 初始化结构体用于配置 SDIO 基本工作环境,比如时钟分频、时钟沿、数据宽度等等。它被SDIO_Init 函数使用。
typedef struct {
uint32_t ClockEdge; // 时钟沿
uint32_t ClockBypass; // 旁路时钟
uint32_t ClockPowerSave; // 节能模式
uint32_t BusWide; // 数据宽度
uint32_t HardwareFlowControl; // 硬件流控制
uint32_t ClockDiv; // 时钟分频
} SDIO_InitTypeDef;
各结构体成员的作用介绍如下:
(1) ClockEdge:主时钟 SDIOCLK 产生 CLK 引脚时钟有效沿选择,可选上升沿或下降沿,它设定 SDIO 时钟控制寄存器 (SDIO_CLKCR) 的 NEGEDGE 位的值,一般选择设置为高电平。
(2) ClockBypass:时钟分频旁路使用,可选使能或禁用,它设定 SDIO_CLKCR 寄存器的BYPASS位。如果使能旁路, SDIOCLK 直接驱动 CLK 线输出时钟;如果禁用,使用 SDIO_CLKCR寄存器的 CLKDIV 位值分频 SDIOCLK,然后输出到 CLK 线。一般选择禁用时钟分频旁路。
(3) ClockPowerSave:节能模式选择,可选使能或禁用,它设定 SDIO_CLKCR 寄存器的PWRSAV位的值。如果使能节能模式, CLK 线只有在总线激活时才有时钟输出;如果禁用节能模式,始终使能 CLK 线输出时钟。
(4) BusWide:数据线宽度选择,可选 1 位数据总线、 4 位数据总线或 8 为数据总线,系统默认使用 1 位数据总线,操作 SD 卡时在数据传输模式下一般选择 4 位数据总线。它设定SDIO_CLKCR 寄存器的 WIDBUS 位的值。
(5) HardwareFlowControl:硬件流控制选择,可选使能或禁用,它设定 SDIO_CLKCR 寄存器的HWFC_EN 位的值。硬件流控制功能可以避免 FIFO 发送上溢和下溢错误。
(6) ClockDiv:时钟分频系数,它设定 SDIO_CLKCR 寄存器的 CLKDIV 位的值,设置 SDIOCLK与 CLK 线输出时钟分频系数:CLK 线时钟频率 =SDIOCLK/([CLKDIV+2])。
7. SDIO 命令初始化结构体
SDIO 命令初始化结构体用于设置命令相关内容,比如命令号、命令参数、响应类型等等。
typedef struct {
uint32_t Argument; // 命令参数
uint32_t CmdIndex; // 命令号
uint32_t Response; // 响应类型
uint32_t WaitForInterrupt; // 等待使能
uint32_t CPSM; // 命令路径状态机
} SDIO_CmdInitTypeDef;
各个结构体成员介绍如下:
(1) Argument:作为命令的一部分发送到卡的命令参数,它设定 SDIO 参数寄存器 (SDIO_ARG)的值。
(2) CmdIndex:命令号选择,它设定 SDIO 命令寄存器 (SDIO_CMD) 的 CMDINDEX 位的值。
(3) Response:响应类型, SDIO 定义两个响应类型:长响应和短响应。根据命令号选择对应的响应类型。 SDIO 定义了四个 32 位的 SDIO 响应寄存器 (SDIO_RESPx,x=1..4),短响应只用到 SDIO_RESP1。
(4) Wait:等待类型选择,有三种状态可选,一种是无等待状态,超时检测功能启动;一种是等待中断,另外一种是等待传输完成。它设定 SDIO_CMD 寄存器的 WAITPEND 位和 WAITINT位的值。
(5) CPSM:命令路径状态机控制,可选使能或禁用 CPSM。它设定 SDIO_CMD 寄存器的CPSMEN位的值。
8. SDIO 数据初始化结构体
SDIO 数据初始化结构体用于配置数据发送和接收参数,比如传输超时、数据长度、传输模式等等。
typedef struct {
uint32_t DataTimeOut; // 数据传输超时
uint32_t DataLength; // 数据长度
uint32_t DataBlockSize; // 数据块大小
uint32_t TransferDir; // 数据传输方向
uint32_t TransferMode; // 数据传输模式
uint32_t DPSM; // 数据路径状态机
} SDIO_DataInitTypeDef;
各结构体成员介绍如下:
(1) DataTimeOut:设置数据传输以卡总线时钟周期表示的超时周期,它设定 SDIO 数据定时器寄存器 (SDIO_DTIMER) 的值。在 DPSM 进入 Wait_R 或繁忙状态后开始递减,直到 0 还处于以上两种状态则将超时状态标志置 1.
(2) DataLength:设置传输数据长度,它设定 SDIO 数据长度寄存器 (SDIO_DLEN) 的值。
(3) DataBlockSize:设置数据块大小,有多种尺寸可选,不同命令要求的数据块可能不同。它设定 SDIO 数据控制寄存器 (SDIO_DCTRL) 寄存器的 DBLOCKSIZE 位的值。
(4) TransferDir:数据传输方向,可选从主机到卡的写操作,或从卡到主机的读操作。它设定SDIO_DCTRL 寄存器的 DTDIR 位的值。
(5) TransferMode:数据传输模式,可选数据块或数据流模式。对于 SD 卡操作使用数据块类型。它设定 SDIO_DCTRL 寄存器的 DTMODE 位的值。
(6) DPSM:数据路径状态机控制,可选使能或禁用 DPSM。它设定 SDIO_DCTRL 寄存器的DTEN 位的值。要实现数据传输都必须使能 SDIO_DPSM。
9. SD 卡读写测试实验
SD 卡广泛用于便携式设备上,比如数码相机、手机、多媒体播放器等。对于嵌入式设备来说是一种重要的存储数据部件。类似于 SPI Flash 芯片数据操作,可以直接进行读写,也可以写入文件系统,然后使用文件系统读写函数,使用文件系统操作。本实验是进行 SD 卡最底层的数据读写操作,直接使用 SDIO 对 SD 卡进行读写,会损坏 SD 卡原本内容,导致数据丢失,实验前请注意备份 SD 卡的原内容。由于 SD 卡容量很大,我们平时使用的 SD 卡都是已经包含有文件系统的,一般不会使用本章的操作方式编写 SD 卡的应用,但它是 SD 卡操作的基础,对于原理学习是非常有必要的,在它的基础上移植文件系统到 SD 卡的应用将在下一章讲解。
9.1 硬件设计

STM32 控制器的 SDIO 引脚是被设计固定不变的,开发板设计采用四根数据线模式。对于命令线
和数据线须需要加一个上拉电阻。
9.2 软件设计
有了之前相关 SDIO 知识基础,我们就可以着手开始编写 SD 卡驱动程序了,根据之前内容,可了解操作的大概流程:
• 初始化相关 GPIO 及 SDIO 外设;
• 配置 SDIO 基本通信环境进入卡识别模式,通过几个命令处理后得到卡类型;
• 如果是可用卡就进入数据传输模式,接下来就可以进行读、写、擦除的操作。
虽然看起来只有三步,但它们有非常多的细节需要处理。实际上, SD 卡是非常常用外设部件,ST公司在其测试板上也有板子 SD 卡卡槽,并提供了完整的驱动程序,我们直接参考移植使用即可。
类似 SDIO、 USB 这些复杂的外设,它们的通信协议相当庞大,要自行编写完整、严谨的驱动不是一件轻松的事情,这时我们就可以利用 ST 官方例程的驱动文件,根据自己硬件移植到自己开发平台即可。
在“初识 STM32 HAL 库”章节我们重点讲解了 HAL 库的源代码及启动文件和库使用帮助文档这两部分内容,实际上“Utilities”文件夹内容是非常有参考价值的,该文件夹包含了基于 ST 官方实验板的驱动文件,比如 LCD、 SDRAM、 SD 卡、音频解码 IC 等等底层驱动程序,另外还有第三方软件库,如 emWin 图像软件库和 FatFs 文件系统。虽然,我们的开发平台跟 ST 官方实验平台硬件设计略有差别,但移植程序方法是完全可行的。学会移植程序可以减少很多工作量,加快项目进程,更何况 ST 官方的驱动代码是经过严格验证的。
在“STM32Cube_FW_F4_V1.19.0DriversBSP”文件路径下可以知道 SD 卡驱动文件,见图 19。
我们需要 stm32746g_discovery_sd.c 和 stm32746g_discovery_sd.h 两个文件的完整内容。另外还需要 stm32746g_discovery.c 和 stm32746g_discovery.h 两个文件的部分代码内容,为简化工程,本章配置工程代码是将这两个文件需要用到的内容移植到 stm32746g_discovery_sd.c 文件中,具体可以参考工程文件。

更多推荐

所有评论(0)