STM32入门学习笔记之SD卡基础读写实验1

电子说

1.2w人已加入

描述

20.1 概述

SD卡是嵌入式系统中最常见的存储器,不仅容量可以做的很大,并且接口通用,支持SPI/SDIO驱动,尺寸可供选择,能满足不同应用的要求。STM32F1系列自带了标准的4位SDIO接口,最高通信速度可达24MHz,最高每秒能传输12M字节的数据。

20.1.1 SDIO框图

STM32F1的SDIO控制器包括2部分,SDIO适配器模块和AHB总线接口,功能框图如下图所示。

SDIO

其中SDIO适配器模块主要用于实现所有MMC/SD卡的相关功能,如时钟的产生,命令和数据的传输,AHB总线接口则用于操作SDIO适配器模块中的寄存器并产生中断和DMA请求信号。复位后默认情况下SDIO_D0用于数据传输。初始化后主机可以改变数据总线的宽度。

如果一个多媒体卡接到了总线上,则SDIO_D0、SDIO_D[3:0]或SDIO_D[7:0]可以用于数据传输。MMC版本V3.31和之前版本的协议只支持1位数据线,所以只能用SDIO_D0(为了通用性考虑,在程序里面我们只要检测到是MMC卡就设置为1位总线数据)。

如果一个SD卡接到了总线上,可以通过主机配置数据传输使用SDIO_D0或SDIO_D[3:0]。所有的数据线都工作在推挽模式。

SDIO_CMD有两种操作模式:

(1)用于初始化时的开路模式(仅用于MMC版本V3.31或之前版本)

(2)用于命令传输的推挽模式(SD卡和MMCV4.2在初始化时也使用推挽驱动)

20.1.2 SDIO时钟

从SDIO框图我们可以看到SDIO总共有3个时钟,分别是:

(1)卡时钟SDIO_CK:每个时钟周期在命令和数据线上传输1位命令或数据。对于多媒体卡V3.31协议,时钟频率可以在0MHz至20MHz间变化;对于多媒体卡V4.0/4.2协议,时钟频率可以在0MHz至48MHz间变化;对于SD卡,时钟频率可以在0MHz至25MHz间变化。

(2)SDIO适配器时钟SDIOCLK:该时钟用于驱动SDIO适配器,其频率等于AHB总线频率HCLK,并用于产生SDIO_CK时钟

(3)AHB总线接口时钟HCLK/2:该时钟用于驱动SDIO的AHB总线接口,其频率为HCLK/2。

我们的SD卡时钟SDIO_CK,根据卡的不同,可能有好几个区间,这就涉及到时钟频率的设置,SDIO_CK与SDIOCLK的关系为:

SDIO_CK=SDIOCLK/(2+CLKDIV)

其中,SDIOCLK为HCLK,一般是72MHz,而CLKDIV则是分配系数,可以通过SDIO的SDIO_CLKCR寄存器进行设置,确保SDIO_CK不超过卡的最大操作频率。

注:在SD卡刚刚初始化的时候,其时钟频率SDIO_CK不能超过400KHz,否则可能无法完成初始化。在初始化以后,就可以设置时钟频率到最大了,但不可超过SD卡的最大操作时钟频率。

20.1.3 SDIO的命令与响应

SDIO的命令分为应用相关命令ACMD和通用命令CMD两部分,应用相关命令ACMD的发送,必须先发送通用命令CMD55,然后才能发送应用相关命令ACMD。SDIO的所有命令和响应都是通过SDIO_CMD引脚传输的,任何命令的长度都是固定为48位,SDIO的命令格式如下表所示。

Bit位 宽度 说明
47 1 0 起始位
46 1 1 传输位
45:40 6 - 命令索引
39:8 32 - 参数
7:1 7 - CRC7
0 1 1 结束位

所有的命令都是由STM32F1发出,其中开始位、传输位、CRC7和结束位由SDIO硬件控制,我们需要设置的就只有命令索引和参数部分。其中命令索引在SDIO_CMD寄存器里面设置,命令参数则由寄存器SDIO_ARG设置。一般情况下,选中的SD卡在接收到命令之后,都会回复一个应答(但是CMD0无应答),这个应答我们称之为响应,响应也是在CMD线上串行传输的。STM32F1的SDIO控制器支持2种响应类型,48位的短响应和136位的长响应,这两种响应类型都带CRC错误检测,不带CRC的响应应该忽略CRC错误标志,如CMD1的响应。

短响应的格式如下表所示。

Bit位 宽度 说明
47 1 0 起始位
46 1 0 传输位
45:40 6 - 命令索引
39:8 32 - 参数
7:1 7 - CRC7或者1111111
0 1 1 结束位

长响应的格式如下表所示。

Bit位 宽度 说明
135 1 0 起始位
134 1 0 传输位
133:128 6 111111 保留
127:1 127 - CID或CSD(包括内部CRC7)
0 1 1 结束位

硬件为我们滤除了开始位、传输位、CRC7以及结束位等信息,对于短响应,命令索引存放在SDIO_RESPCMD寄存器,参数则存放在SDIO_RESP1寄存器里面。对于长响应,则仅留CID/CSD位域,存放在SDIO_RESP1到SDIO_RESP4等4个寄存器。SD卡总共有5类响应(R1、R2、R3、R6、R7),这里以R1为例简单介绍一下。R1(普通响应命令)响应属于短响应,其长度为48位,R1响应的格式如下表所示。

Bit位 宽度 说明
47 1 0 起始位
46 1 1 传输位
45:40 6 X 命令索引
39:8 32 X 参数
7:1 7 X CRC7
0 1 1 结束位

在收到R1响应后,我们可以从SDIO_RESPCMD寄存器和SDIO_RESP1寄存器分别读出命令索引和卡状态信息。

20.1.4 数据块读操作

对于SD卡,数据是以数据块的形式传输的,我们常用的卡就是SD卡,所以不考虑MMC形式的读写操作,因为MMC卡数据以数据块或者数据流的形式传输。

从机在收到主机相关命令后,开始发送数据块给主机,所有数据块都带有CRC校验值,CRC由SDIO硬件自动处理,单个数据块读的时候,在收到1个数据块以后即可以停止了,不需要发送停止命令CMD12。但是多块数据读的时候,SD卡将一直发送数据给主机,直到接到主机发送的STOP命令CMD12。

SDIO多数据块的读操作如下图所示。

SDIO

20.1.5 数据块写操作

数据块写操作同数据块读操作基本类似,只是数据块写的时候,多了一个忙判断,新的数据块必须在SD卡非忙的时候发送。这里的忙信号由SD卡拉低SDIO_D0,以表示忙,SDIO硬件自动控制,不需要我们软件处理。

SDIO

20.2 SDIO相关寄存器

20.2.1 SDIO电源控制寄存器:SDIO_POWER

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
- CTRL

Bit 1~Bit 0:电源控制位

00:电源关闭,卡的时钟停止

01:保留

10:保留的上电状态

11:上电状态,卡的时钟开启

20.2.2 SDIO时钟控制寄存器:SDIO_CLKCR

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
-
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
- HWFC_EN NEGEDGE WIDBUS BYPASS PWRSAV CLKEN CLKDIV

Bit 14:硬件流控制使能

0:关闭硬件流控制

1:使能硬件流控制

Bit 13:SDIO_CK相位选择位

0:在主时钟SDIOCLK的上升沿产生SDIO_CK

1:在主时钟SDIOCLK的下降沿产生SDIO_CK

Bit 12~Bit 11:宽总线模式使能位

00:默认总线模式,使用SDIO_D0

01:4位总线模式,使用SDIO_D[3:0]

10:8位总线模式,使用SDIO_D[7:0]

Bit 10:旁路时钟分频器

0:关闭旁路:驱动SDIO_CK输出信号之前,依据CLKDIV数值对SDIOCLK分频

1:使能旁路:SDIOCLK直接驱动SDIO_CK输出信号

Bit 9:省电配置位(为了省电,当总线为空闲时,设置PWRSAV位可以关闭SDIO_CK时钟输出)

0:始终输出SDIO_CK

1:仅在有总线活动时才输出SDIO_CK

Bit 8:时钟使能位

0:SDIO_CK关闭

1:SDIO_CK使能

Bit 7~Bit 0:时钟分频系数

这个域定义了输入时钟(SDIOCLK)与输出时钟(SDIO_CK)间的分频系数:SDIO_CK频率=SDIOCLK/[CLKDIV+2]

20.2.3 SDIO参数寄存器:SDIO_ARG

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
CMDARG[31:16]
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
CMDARG[16:0]

Bit 31~Bit 0:命令参数

属于发送到卡中命令的一部分,如果一个命令包含一个参数,必须在写命令到命令寄存器之前加载这个寄存器

20.2.4 SDIO命令响应寄存器:SDIO_RESPCMD

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
-
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
- RESPCMD

Bit 5~Bit 0:响应的命令索引

只读位,包含最后收到的命令响应中的命令索引

20.2.5 SDIO相应寄存器组:SDIO_RESP1~SDIO_RESP4

寄存器 短响应 长响应
SDIO_RESP1 卡状态[31:0] 卡状态[127:96]
SDIO_RESP2 未使用 卡状态[95:64]
SDIO_RESP3 未使用 卡状态[31:0]
SDIO_RESP4 未使用 卡状态[31:0]

注:总是先收到卡状态的最高位,SDIO_RESP3寄存器的最低位始终为0。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分