STM32-SD卡读写

注:参考野火SD卡教程。[a:b]表示地址长度,例如:[31:0]就表示32位的地址长度。

一、简介

        SD卡(Secure Digital Memory Card)在我们生活中已经非常普遍了,控制器对SD卡进行读写通信操作一般有两种通信接口可选, 一种是SPI接口,另外一种就是SDIO接口。SDIO全称是安全数字输入/输出接口,多媒体卡(MMC)、SD卡、SD I/O卡都有SDIO接口。 stm32f4xx系列控制器有一个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是专为轻薄笔记本硬盘设计的硬盘高速通讯接口。

 二、SD卡物理结构

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

三、SDIO总线 

SD卡一般都支持SDIO和SPI这两种接口,本章内容只介绍SDIO接口操作方式,如果需要使用SPI操作方式可以参考SPI相关章节。 另外,stm32f4xx系列控制器的SDIO是不支持SPI通信模式的,如果需要用到SPI通信只能使用SPI外设。

SD卡总线拓扑参考图 SD卡总线拓扑。虽然可以共用总线, 但不推荐多卡槽共用总线信号,要求一个单独SD总线应该连接一个单独的SD卡。

SD卡使用9-pin接口通信,其中3根电源线、1根时钟线、1根命令线和4根数据线,具体说明如下:

  • CLK:时钟线,由SDIO主机产生,即由STM32控制器输出;

  • CMD:命令控制线,SDIO主机通过该线发送命令控制SD卡,如果命令要求SD卡提供应答(响应),SD卡也是通过该线传输应答信息;

  • D0-3:数据线,传输读写数据;SD卡可将D0拉低表示忙状态;

  • VDD、VSS1、VSS2:电源和地信号。

 SDIO不管是从主机控制器向SD卡传输, 还是SD卡向主机控制器传输都只以CLK时钟线的上升沿为有效。SD卡操作过程会使用两种不同频率的时钟同步数据,一个是识别卡阶段时钟频率FOD, 最高为400kHz,另外一个是数据传输模式下时钟频率FPP,默认最高为25MHz,如果通过相关寄存器配置使SDIO工作在高速模式,此时数据传输模式最高频率为50MHz。

四、总线协议

SD总线通信是基于命令和数据传输的。通讯由一个起始位(“0”),由一个停止位(“1”)终止。SD通信一般是主机发送一个命令(Command), 从设备在接收到命令后作出响应(Response),如有需要会有数据(Data)传输参与。

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

 SD数据传输支持单块和多块读写,它们分别对应不同的操作命令,多块写入还需要使用命令来停止整个写入操作。 数据写入前需要检测SD卡忙状态,因为SD卡在接收到数据后编程到存储区过程需要一定操作时间。SD卡忙状态通过把D0线拉低表示。

数据块读操作与之类似,只是无需忙状态检测。

使用4数据线传输时,每次传输4bit数据,每根数据线都必须有起始位、终止位以及CRC位,CRC位每根数据线都要分别检查,并把检查结果汇总然后在数据传输完后通过D0线反馈给主机。

SD卡数据包有两种格式,一种是常规数据(8bit宽),它先发低字节再发高字节,而每个字节则是先发高位再发低位,4线传输示意如图 8位宽数据包传输

4线同步发送,每根线发送一个字节的其中两个位,数据位在四线顺序排列发送,DAT3数据线发较高位,DAT0数据线发较低位。

另外一种数据包发送格式是宽位数据包格式,对SD卡而言宽位数据包发送方式是针对SD卡SSR(SD状态)寄存器内容发送的, SSR寄存器总共有512bit,在主机发出ACMD13命令后SD卡将SSR寄存器内容通过DAT线发送给主机。宽位数据包格式示意见图 宽位数据包传输

五、命令及响应

1.命令格式

SD命令格式固定为48bit,都是通过CMD线连续传输的(数据线不参与)。

SD命令的组成如下:

  • 起始位和终止位:命令的主体包含在起始位与终止位之间,它们都只包含一个数据位,起始位为0,终止位为1。

  • 传输标志:用于区分传输方向,该位为1时表示命令,方向为主机传输到SD卡,该位为0时表示响应,方向为SD卡传输到主机。

命令主体内容包括命令、地址信息/参数和CRC校验三个部分。

  • 命令号:它固定占用6bit,所以总共有64个命令(代号:CMD0~CMD63),每个命令都有特定的用途, 部分命令不适用于SD卡操作,只是专门用于MMC卡或者SD I/O卡。

  • 地址/参数:每个命令有32bit地址信息/参数用于命令附加内容,例如,广播命令没有地址信息, 这32bit用于指定参数,而寻址命令这32bit用于指定目标SD卡的地址。

  • CRC7校验:长度为7bit的校验位用于验证命令传输内容正确性, 如果发生外部干扰导致传输数据个别位状态改变将导致校准失败,也意味着命令传输失败,SD卡不执行命令。

 2.命令类型

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

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

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

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

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

常见命令

 3.响应

响应由SD卡向主机发出,部分命令要求SD卡作出响应,这些响应多用于反馈SD卡的状态。SDIO总共有7个响应类型(代号:R1~R7), 其中SD卡没有R4、R5类型响应。特定的命令对应有特定的响应类型,比如当主机发送CMD3命令时,可以得到响应R6。与命令一样, SD卡的响应也是通过CMD线连续传输的。根据响应内容大小可以分为短响应和长响应。短响应是48bit长度, 只有R2类型是长响应,其长度为136bit。

除了R3类型之外,其他响应都使用CRC7校验来校验,对于R2类型是使用CID和CSD寄存器内部CRC7。

六、SD卡的操作模式及切换 

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

1. 卡识别模式

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

主机上电后,所有卡处于空闲状态,包括当前处于无效状态的卡。主机也可以发送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之后也进入数据传输模式。

 2.数据传输模式

只有SD卡系统处于数据传输模式下才可以进行数据读写操作。数据传输模式下可以将主机SD时钟频率设置为FPP,默认最高为25MHz, 频率切换可以通过CMD4命令来实现。

CMD7用来选定和取消指定的卡,卡在待机状态下还不能进行数据通信,因为总线上可能有多个卡都是出于待机状态, 必须选择一个RCA地址目标卡使其进入传输状态才可以进行数据通信。同时通过CMD7命令也可以让已经被选择的目标卡返回到待机状态。

数据传输模式下的数据通信都是主机和目标卡之间通过寻址命令点对点进行的。 卡处于传输状态下可以使用表 SD部分命令描述 中面向块的读写以及擦除命令对卡进行数据读写、擦除。 CMD12可以中断正在进行的数据通信,让卡返回到传输状态。CMD0和CMD15会中止任何数据编程操作, 返回卡识别模式,这可能导致卡数据被损坏。

七、SDIO功能框图

 

SDIO使用两个时钟信号,一个是SDIO适配器时钟(SDIOCLK=48MHz),另外一个是APB2总线时钟(PCLK2,一般为84MHz)。

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卡最多用四根数据线。

SDIO适配器是SD卡系统主机部分,是STM32控制器与SD卡数据通信中间设备。SDIO适配器由五个单元组成, 分别是控制单元、命令路径单元、数据路径单元、寄存器单元以及FIFO。

1.控制单元 

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

2.命令路径 

命令路径控制命令发送,并接收卡的响应。

3.数据路径

数据路径部件负责与SD卡相互数据传输。

 4.数据FIFO

数据FIFO(先进先出)部件是一个数据缓冲器,带发送和接收单元。控制器的FIFO包含宽度为32bit、 深度为32字的数据缓冲器和发送/接收逻辑。其中SDIO状态寄存器(SDIO_STA)的TXACT位用于指示当前正在发送数据, RXACT位指示当前正在接收数据,这两个位不可能同时为1。

  • 当TXACT为1时,可以通过APB2接口将数据写入到传输FIFO。

  • 当RXACT为1时,接收FIFO存放从数据路径部件接收到的数据。

根据FIFO空或满状态会把SDIO_STA寄存器位值1,并可以产生中断和DMA请求。

八、SDIO配置

1.SDIO初始化结构体

typedef struct {
    uint32_t SDIO_ClockEdge;              // 时钟沿
    uint32_t SDIO_ClockBypass;           // 旁路时钟
    uint32_t SDIO_ClockPowerSave;        // 节能模式
    uint32_t SDIO_BusWide;                // 数据宽度
    uint32_t SDIO_HardwareFlowControl;  // 硬件流控制
    uint8_t SDIO_ClockDiv;                // 时钟分频
} SDIO_InitTypeDef;

各结构体成员的作用介绍如下:

(1) SDIO_ClockEdge:主时钟SDIOCLK产生CLK引脚时钟有效沿选择,可选上升沿或下降沿, 它设定SDIO时钟控制寄存器(SDIO_CLKCR)的NEGEDGE位的值,一般选择设置为高电平。

(2)SDIO_ClockBypass:时钟分频旁路使用,可选使能或禁用,它设定SDIO_CLKCR寄存器的BYPASS位。如果使能旁路,SDIOCLK直接驱动CLK线输出时钟; 如果禁用,使用SDIO_CLKCR寄存器的CLKDIV位值分频SDIOCLK,然后输出到CLK线。一般选择禁用时钟分频旁路。

(3) SDIO_ClockPowerSave:节能模式选择,可选使能或禁用,它设定SDIO_CLKCR寄存器的PWRSAV位的值。如果使能节能模式, CLK线只有在总线激活时才有时钟输出;如果禁用节能模式,始终使能CLK线输出时钟。

(4) SDIO_BusWide:数据线宽度选择,可选1位数据总线、4位数据总线或8为数据总线,系统默认使用1位数据总线, 操作SD卡时在数据传输模式下一般选择4位数据总线。它设定SDIO_CLKCR寄存器的WIDBUS位的值。

(5) SDIO_HardwareFlowControl:硬件流控制选择,可选使能或禁用,它设定SDIO_CLKCR寄存器的HWFC_EN位的值。 硬件流控制功能可以避免FIFO发送上溢和下溢错误。

(6) SDIO_ClockDiv:时钟分频系数,它设定SDIO_CLKCR寄存器的CLKDIV位的值, 设置SDIOCLK与CLK线输出时钟分频系数:

CLK线时钟频率=SDIOCLK/([CLKDIV+2])。

 2.SDIO命令初始化结构体

typedef struct {
    uint32_t SDIO_Argument; // 命令参数
    uint32_t SDIO_CmdIndex; // 命令号
    uint32_t SDIO_Response; // 响应类型
    uint32_t SDIO_Wait;     // 等待使能
    uint32_t SDIO_CPSM;     // 命令路径状态机
} SDIO_CmdInitTypeDef;

各个结构体成员介绍如下:

(1) SDIO_Argument:作为命令的一部分发送到卡的命令参数, 它设定SDIO参数寄存器(SDIO_ARG)的值。

(2) SDIO_CmdIndex:命令号选择, 它设定SDIO命令寄存器(SDIO_CMD)的CMDINDEX位的值。

(3) SDIO_Response:响应类型,SDIO定义两个响应类型:长响应和短响应。根据命令号选择对应的响应类型。 SDIO定义了四个32位的SDIO响应寄存器(SDIO_RESPx,x=1..4),短响应只用到SDIO_RESP1。

(4) SDIO_Wait:等待类型选择,有三种状态可选,一种是无等待状态,超时检测功能启动;一种是等待中断, 另外一种是等待传输完成。它设定SDIO_CMD寄存器的WAITPEND位和WAITINT位的值。

(5) SDIO_CPSM:命令路径状态机控制,可选使能或禁用CPSM。 它设定SDIO_CMD寄存器的CPSMEN位的值。

3.SDIO数据初始化结构体

typedef struct {
    uint32_t SDIO_DataTimeOut;    // 数据传输超时
    uint32_t SDIO_DataLength;     // 数据长度
    uint32_t SDIO_DataBlockSize;  // 数据块大小
    uint32_t SDIO_TransferDir;    // 数据传输方向
    uint32_t SDIO_TransferMode;   // 数据传输模式
    uint32_t SDIO_DPSM;           // 数据路径状态机
} SDIO_DataInitTypeDef;

各结构体成员介绍如下:

(1) SDIO_DataTimeOut:设置数据传输以卡总线时钟周期表示的超时周期,它设定SDIO数据定时器寄存器(SDIO_DTIMER)的值。 在DPSM进入Wait_R或繁忙状态后开始递减,直到0还处于以上两种状态则将超时状态标志置1.

(2) SDIO_DataLength:设置传输数据长度, 它设定SDIO数据长度寄存器(SDIO_DLEN)的值。

(3) SDIO_DataBlockSize:设置数据块大小,有多种尺寸可选, 不同命令要求的数据块可能不同。它设定SDIO数据控制寄存器(SDIO_DCTRL)寄存器的DBLOCKSIZE位的值。

(4) SDIO_TransferDir:数据传输方向,可选从主机到卡的写操作, 或从卡到主机的读操作。它设定SDIO_DCTRL寄存器的DTDIR位的值。

(5) SDIO_TransferMode:数据传输模式,可选数据块或数据流模式。 对于SD卡操作使用数据块类型。它设定SDIO_DCTRL寄存器的DTMODE位的值。

(6) SDIO_DPSM:数据路径状态机控制,可选使能或禁用DPSM。 它设定SDIO_DCTRL寄存器的DTEN位的值。要实现数据传输都必须使能SDIO_DPSM。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值