SD卡和SDIO
SDIO (1)简介 SDIO,全称: Secure Digital Input and Output ,即安全数字输入输出接口。它是在SD卡接口的基础上发展而来,它可以兼容之前的SD卡,并可以连接SDIO接口设备,例如:蓝牙、WIFI、照相机等。 SDIO和SD卡规范间的一个重要区别是增加了低速标准。低速卡的目标应用是以最小的硬件开支支持低速I/ O能力。低速卡支持类似调制解调器、条码扫描仪和GPS接收器等应用。 STM32的SDIO控制器支持多媒体卡(MMC卡)、SD存储卡、SD I/O卡和CE-ATA设备。 (2)STM32 SDIO接口特点 ①与多媒体卡系统规格书版本4.2全兼容。支持三种不同的数据总线模式:1位(默认)、4位和8位。 ②与较早的多媒体卡系统规格版本全兼容(向前兼容)。 ③与SD存储卡规格版本2.0全兼容。 ④与SD I/O卡规格版本2.0全兼容:支持两种不同的数据总线模式:1位(默认)和4位。(MMC多媒体卡支持1位、4位和8位) ⑤完全支持CE-ATA功能(与CE-ATA数字协议版本1.1全兼容)。 8位总线模式下数据传输速率可达48MHz。 (即48M字节/秒) ⑥数据和命令输出使能信号,用于控制外部双向驱动器。
stm32f407的SDIO框图 stm32f103的SDIO框图 由图可知,上述两SDIO的框图不同之处在于总线接口不同,时钟频率也不同 卡时钟(SDIO_CK):每个时钟周期在命令和数据线上传输1位命令或数据。对于SD或SD I/O卡,时钟频率可以在0MHz至25MHz间变化。 SDIO适配器时钟(SDIOCLK):该时钟用于驱动SDIO适配器,可用于产生SDIO_CK时钟。对F1来说,SDIOCLK来自HCLK(72Mhz,系统时钟);对F4来说,SDIOCLK来自PLL48CK(48Mhz)。 F1:AHB总线接口时钟(HCLK/2):该时钟用于驱动SDIO的AHB总线接口,其频率为HCLK/2=36Mhz。 F4:APB2总线接口时钟(PCLK2):该时钟用于驱动SDIO的APB2总线 接口,其频率为PCLK2=84Mhz。 SDIO_CK计算公式:SDIO_CK=SDIOCLK/(2+CLKDIV) 其中CLKDIV为分频器设置的分频系数
复位后SDIO_D0用于数据传输。初始化后主机可以改变数据总线的宽度(通过ACMD6命令设置为1位或者是4位)。 如果一个多媒体卡接到了总线上,则SDIO_D0、SDIO_D[3:0]或SDIO_D[7:0]可以用于数据传输。 MMC版本V3.31和之前版本的协议只支持1位数据线,所以只能用SDIO_D0(为了通用性考虑,在程序里面我们只要检测到是MMC卡就设置为1位总线数据)。 (3)SDIO的命令与响应 SDIO的命令分为:应用相关命令(ACMD)和通用命令(CMD)两部分。发送ACMD时,需先发送CMD55。 SDIO所有的命令和响应都是在SDIO_CMD引脚上面传输的,命令长度固定为48位,SDIO命令格式如下表所示
其中除了命令索引和参数需要我们设置,其他都是由SDIO硬件自动控制。命令索引(如CMD0,CMD1之类)由SDIO_CMD寄存器设置,命令参数则由SDIO_ARG寄存器设置。
一般SD卡在接收到命令行后,都会有一个应答(CMD0例外),这个应答也称之为响应。STM32的SDIO接口,支持2种响应类型:短响应(48位)和长响应(136位)。
STM32 SDIO短响应(48位)格式如下表所示: STM32 SDIO长响应(136位)格式如下表所示 不论是短响应还是长响应,硬件都会自动滤除起始位、传输位、CRC7以及结束位等信息,对于短响应,命令索引存放在SDIO_RESPCMD寄存器,参数则存放在SDIO_RESP1寄存器里面。对于长响应,则仅留CID/CSD位域,存放在SDIO_RESP1~SDIO_RESP4等4个寄存器。
SD卡总共有6类响应(R1、R1b、R2、R3、R6、R7): R1(正常响应命令) 代码长度 = 48 位。45:40 位用于指示待响应命令的索引,该值被解释为二进制编码的数字 (介于 0 和 63 之间)。卡的状态采用 32 位进行编码。 R1b 同 R1,并且有一个可选的繁忙信号在数据线上传输。根据卡在接收命令之前所处的状态, SD卡在接收到这些命令之后可能会变为繁忙状态。
R2(CID 和 CSD 寄存器) 代码长度 = 136 位。发送 CID 寄存器的内容以响应 CMD2 和 CMD10 命令。发送 CSD 寄存 器的内容以响应 CMD9。仅传输 CID 和 CSD 的位 [127…1],这些寄存器的保留位 [0] 将被替 换为响应的结束位。卡通过将MCDAT 保持低电平来指示擦除正在进行中。实际擦除时间可 能很长,主机可以发出 CMD7 来取消选择卡 R3(OCR 寄存器) 代码长度:48 位。发送 OCR 寄存器的内容以响应 CMD1。电平编码如下所示:受限电压窗口 = 低电平,卡繁忙 = 低电平 R6 仅用于 SD I/O。存储设备对 CMD3 的正常响应。
R7 R7 响应长度为48位。是发送卡支持电压信息对CMD8的响应。位19 -16表示该卡所支持的电压范围。接受所提供电压的卡返回R7响应。在响应中,卡将同时返回电压范围和检查模式 (4)SDIO块数据传输 SDIO与SD卡通信一般以数据块的形式进行传输,SDIO(多)数据块读操作,如下图所示: 从机在收到主机相关命令后,开始发送数据块给主机,所有数据块都带CRC校验(由硬件自动处理),单个数据块读的时候,在收到1个数据块以后即可以停止了,不需要发送停止命令(CMD12)。但是多块数据读的时候,SD卡将一直发送数据给主机,直到接到主机发送的STOP命令(CMD12)。SDIO(多)数据块写操作,如下图所示: 数据块写操作同数据块读操作基本类似,只是数据块写的时候,多了一个繁忙判断,新的数据块必须在SD卡非繁忙的时候发送。这里的繁忙信号由SD卡拉低SDIO_D0,以表示繁忙,SDIO硬件自动控制,不需要软件处理。 注意: 只要发出“繁忙”信号(SDIO_D0 被拉到低电平),SDIO 便不会发送任何数据。 另外还有连续读取和连续写入操作: (5)SDIO寄存器
①SDIO电源控制器SDIO_POWER 该寄存器只有最低2位(PWRCTRL[1:0])有效,其他都是保留位,STM32复位以后,PWRCTRL=00,处于掉电状态。使用前首先要给SDIO上电,应设置这两个位为11。 ②SDIO_CLKCR时钟控制寄存器 注意:当SDIO_CK频率过快时,可能导致SD卡通信失败,此时建议降低SDIO_CK。 ③SDIO参数寄存器SDIO_ARG 该寄存器用于存储命令参数。参数必须先于命令写入。 ④SDIO命令寄存器SDIO_CMD 注意: 写入数据后,在三个 SDIOCLK (48 MHz) 时钟周期以及两个 PCLK2 时钟周期内无法向该寄 存器写入数据。 MMC 可以发送两种类型的响应:短响应(48 位)或长响应(136 位)。SD 卡和 SD I/O 卡则只能发送短响应,参数因响应类型而异:软件将根据发送的命令区分响应类型。CE-ATA 设备仅发送短响应。命令通道状态机我们一般都是开启的,所以位10要设置为1。 命令路径状态机 (CPSM) — 写入命令寄存器并且将使能位置 1 后,命令传输将开始。发送了命令后,命令路径 状态机 (CPSM) 将将状态标志置 1,并且在不需要响应时进入空闲状态。如果需要 响应,则等待响应(请参见第 776 页的图 317)。收到响应时,将比较生成的 CRC 代码和内部生成代码,并且将相应的状态标志置 1。 进入等待状态后,命令计时器便开始运行。如果 CPSM 尚未变为接收状态便已达到超时,则将超时标志置 1 并且进入空闲状态。 注意: 命令超时为固定值:64 个 SDIO_CK 时钟周期。 如果在命令寄存器中将中断位置 1,则禁止计时器运行并且 CPSM 等待来自其中一个卡的中断请求。如果在命令寄存器中将挂起位置 1,则 CPSM 进入挂起状态并等待来自数据路径子单元的 CmdPend 信号。检测到 CmdPend 时,CPSM 将变为发送状态。这会使能数据计数器,用以触发停止命令传输。 注意: CPSM 保持空闲状态至少八个 SDIO_CK 周期以满足 NCC 和 NRC 时序限制。NCC 是两个主 机命令之间的最小延迟,NRC 是主机命令和卡响应之间的最小延迟。 ⑤SDIO命令响应寄存器SDIO_RESPCMD 该寄存器只有低6位有效,比较简单,用于存储最后收到的命令响应中的命令索引。如果传输的命令响应不包含命令索引,则该寄存器的内容不可预知。 ⑥SDIO命令响应1-4寄存器SDIO__RESPx (x=1~4) 命令响应寄存器组,总共包含4个32位寄存器组成,用于存放接收到的卡响应部分的信息。如果收到短响应,则数据存放在SDIO_RESP1寄存器里面,其他三个寄存器没有用到。而如果收到长响应,则依次存放在SDIO_RESP1~ SDIO_RESP4里面 ⑦SDIO数据定时寄存器SDIO_DTIMER 该寄存器用于存储以卡总线时钟(SDIO_CK)为周期的数据超时时间,一个计数器将从SDIO_DTIMER寄存器加载数值,并在数据通道状态机(DPSM)进入Wait_R或繁忙状态时进行递减计数,当DPSM处在这些状态时,如果计数器减为0,则设置超时标志。 注意:在写入数据控制寄存器(SDIO_DCTRL)进行数据传输之前,须先写入该寄存器(SDIO_DTIMER)和数据长度寄存器(SDIO_DLEN). ⑧SDIO数据长度寄存器SDIO_DLEN 该寄存器低25位有效,用于设置需要传输的数据字节长度。对于块数据传输,该寄存器的数值,必须是数据块长度(通过SDIO_DCTRL设置)的倍数。 例:假定数据块大小为512字节,那么SDIO_DLEN的设置,必须是512的整数倍,最大可以设置读取65535个数据块 ⑨SDIO数据控制寄存器SDIO_DCTRL 该寄存器用于控制数据通道状态机(DPSM),包括数据传输使能、传输方向、传输模式、DMA使能、数据块长度等信息的设置。 ⑩SDIO状态寄存器SDIO_STA 状态寄存器可以用来查询SDIO控制器的当前状态,以便处理各种事务。比如SDIO_STA的位2表示命令响应超时,说明SDIO的命令响应出了问题。则通过设置SDIO_ICR的位2则可以清除这个超时标志。 另外,SDIO的清除中断寄存器(SDIO_ICR,一个只写寄存器。以 1 写入某个位会将 SDIO_STA 状态寄存器中的对应位清零)和中断屏蔽寄存器(SDIO_MASK,通过将对应的位置 1 来确定哪一个状态标志位可以产生中断),这两个寄存器和状态寄存器(SDIO_STA)每个位的定义都相同,只是功能各有不同,因此使用时更方便。 11)SDIO数据FIFO寄存器SDIO_FIFO 数据FIFO寄存器包括接收和发送FIFO,各由一组连续的32个地址上的32个寄存器组成,CPU可以使用FIFO读写多个操作数。如果要从SD卡读数据,就必须读SDIO_FIFO寄存器,要写数据到SD卡,则要写SDIO_FIFO寄存器。SDIO将这32个地址分为16个一组,发送接收各占一半。而每次读写的时候,最多就是读取接收FIFO或写入发送FIFO的一半大小的数据,也就是8个字(32个字节)。 注意:操作SDIO_FIFO必须是以4字节对齐的内存操作,否则可能出错。
部分CMD命令
SD卡 简介 SD卡(Secure Digital Memory Card)即:安全数码卡,它是在MMC的基础上发展而来,是一种基于半导体快闪记忆器的新一代记忆设备,它被广泛地于便携式装置上使用,例如数码相机、个人数码助理(PDA)和多媒体播放器等。 SD卡按容量分类,可以分为3类:SD卡、SDHC卡、SDXC卡,如下表所示: SD卡由9个引脚与外部通信,支持SPI和SDIO两种模式,不同模式下,SD卡引脚功能描述如下表所示: 特点:①高容量,最大可达2TB。②高安全性。 ③高速,目前已有读取速度近100MB/S的SD卡。④体积小巧。⑤接口简单,支持SPI和SDIO两种访问模式。 注意:TF卡+卡套,组合起来也可以当SD卡用,但是很大一部分TF卡不支持SPI访问模式。所以SPI驱动SD卡的时候,尽量选择大卡(SD卡),而不要选择TF卡。
SD卡一般有五个寄存器
SD卡初始化流程 不管什么卡(4类:SD2.0高容量卡(SDHC,最大32G),SD2.0标准容量卡(SDSC,最大2G),SD1.x卡和MMC卡),首先执行卡上电(设置SDIO_POWER[1:0]=11),上电后发送CMD0,对卡进行软复位,之后发送CMD8命令,用于区分SD卡2.0,只有2.0及以后的卡才支持CMD8命令,MMC卡和V1.x的卡不支持该命令的。 CMD8命令格式如下表: 在发送CMD8的时候,通过其带的参数设置VHS位,以告诉SD卡主机的供电情况,让SD卡知道主机的供电范围。 VHS位定义如下所示 使用参数0X1AA即告诉SD卡,主机供电为2.7~3.6V之间,如果SD卡支持CMD8,且支持该电压范围,则会通过CMD8的响应(R7)将参数部分原本返回给主机,如果不支持CMD8,或者不支持这个电压范围,则不响应。 在发送CMD8后,发送ACMD41(发送ACMD41之前,要先发送CMD55),来进一步确认卡的操作电压范围,并通过HCS位来告诉SD卡,主机是不是支持高容量卡(SDHC)。 ACMD41命令格式如下 ACMD41指令响应(R3),包含了SD卡OCR寄存器内容,其定义如下所示:
对于支持CMD8的卡,主机设置ACMD41的参数HCS=1,告诉SD卡,主机支持SDHC卡。对2.0的卡,OCR的CCS位用于表示SDHC还是SDSC;对1.x的卡,则忽略该位;对MMC卡,则不支持ACMD41,MMC卡只需要发送:CMD0和CMD1即可完成初始化。 CMD2用于获取CID寄存器数据,CID寄存器各位定义如下 SD卡在收到CMD2后,将返回R2长响应(136位),其中包含128位有效数据(CID寄存器内容),存放在SDIO_RESP1~4等4个寄存器里面。通过读取这四个寄存器,就可以获得SD卡的CID信息。
CMD3,用于设置卡相对地址(RCA,必须为非0),对于SD卡(非MMC卡),在收到CMD3后,将返回一个新的RCA给主机,方便主机寻址。RCA的存在允许一个SDIO接口挂多个SD卡,通过RCA来区分主机要操作的是哪个卡。对于MMC卡,则不是由SD卡自动返回RCA,而是主机主动设置MMC卡的RCA,即通过CMD3带参数(高16位用于RCA设置),实现RCA设置。同样MMC卡也支持一个SDIO接口挂多个MMC卡,不同于SD卡的是所有的RCA都是由主机主动设置的,而SD卡的RCA则是SD卡发给主机的。 在获得卡RCA之后,我们便可以发送CMD9(带RCA参数),获得SD卡的CSD寄存器内容,从CSD寄存器,我们可以得到SD卡的容量和扇区大小等十分重要的信息。最后通过CMD7命令,选中要操作的SD卡即可开始对SD卡的读写操作。
SD卡读数据 SD卡单块数据读取流程 (1)发送CMD16指令,设置数据块大小(2)等待CMD16响应(R1) (3)等待响应后,发送CMD17指令,开始读数据块(4)等待CMD17响应(R1)(5)读一个数据块的数据,完成单块读取 注意:CMD16设置的数据块大小一般为512字节,此设置直接决定SD卡的块大小,SD卡默认的块大小失效。 SD卡多块数据块读取流程 (1)发送CMD16指令,设置数据块大小(2)等待CMD16响应(R1) (3)发送CMD18指令,开始读数据块(4)等待CMD18响应(R1) (5)读第一个数据块的数据(6)读第二个数据块的数据……读取第N个数据块的数据(7)(不读时)发送CMD12指令,结束数据块读取(8)等待CMD12响应(R1)(9)结束多块数据块读取
CMD指令(补充上文中部分) CMD16(对SDHC不起作用) CMD17 CMD18 CMD12 CMD13 CMD24 CMD23 发送ACMD之前,必须先发送CMD55,通知SD卡,接下来要发送的是应用命令(APP CMD),而非标准命令 CMD55 CMD25
SD卡写数据流程 (1)发送CMD16指令设置数据块大小,等待响应(2)发送CMD13指令查询卡状态,等待响应(3)等待READY_FOR_DATA位=1(4)发送CMD24指令开始写入数据(5)写一个数据块的数据,完成单块写入(省略了部分响应步骤) SD卡多块数据块写入流程 (1)发送CMD16指令,设置数据块大小;(2)发送ACMD23指令(该指令仅对SD卡有效。另外,在ACMD指令发送之前,需先发送CMD55),预测出数据块(3)发送CMD25指令,开始写数据块(4)写入第一个数据块的数据(5)写入第二个数据块的数据……写入第n个数据块的数据(6)(不写时)发送CMD12指令,结束数据块写入;(7)发送CMD13指令,查询卡状态(8)等待SD卡写入过程结束(9)完成写入
|