你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【stm32f407】SD协议(一)-SDIO

[复制链接]
aimejia 发布时间:2018-5-29 13:16
本帖最后由 aimejia 于 2018-5-29 17:16 编辑
$ P! \, ]; j6 J5 n5 y3 C9 n  I
* Y5 H3 ]- {1 _, U4 T8 R+ w0 WSDIO简介
: N; b0 N/ `& H
" t  ^* w* r1 }: q* {  v( k1.      SDIO主要功能及框图8 j) f# Y7 }- W. [. P
STM32F4的SDIO控制器支持多媒体卡(MMC卡)、SD存储卡、SD I/O卡和CE-ATA设备等。SDIO的主要功能如下:
$ V  Q2 v6 r! e; a; Z/ O4 f# ~, v
* j; T, \2 {$ Q. r1)      与多媒体卡系统规格书版本4.2全兼容。支持三种不同的数据总线模式:1位(默认)、4位和8位。9 g6 U$ K, W; @' a6 p! z1 F

# o! f3 a1 Z- ?. V& S) O! o2)      与较早的多媒体卡系统规格版本全兼容(向前兼容)。
: b( r: @& C9 }6 u2 D- N$ q) d  f$ A$ v
3)      与SD存储卡规格版本2.0全兼容。
9 D0 V/ o+ k0 s9 Y4 o" V
3 H1 A4 {  {+ Y/ |  v4)      与SD I/O卡规格版本2.0全兼容:支持良种不同的数据总线模式:1位(默认)和4位。' [. S% @+ H7 H3 \

# l9 G1 Z! |* T. p* x5)      完全支持CE-ATA功能(与CE-ATA数字协议版本1.1全兼容)。  8位总线模式下数据传输速率可达48MHz(分频器旁路时)。
3 `8 f+ Q# d! `8 D% q6 A" D% r4 J/ S1 j4 K% x# n8 X
6)      数据和命令输出使能信号,用于控制外部双向驱动器。
9 y. U7 f! }; D3 u
. M0 S$ b- D7 kSTM32F4的SDIO控制器包含2个部分:SDIO适配器模块和APB2总线接口,其功能框图如图所示8 F6 W% n; g2 \! k! ]

7 S4 h+ K* Y. [- }; R  }
1.png

# L5 K4 E& _8 A% v- o" ^复位后默认情况下SDIO_D0用于数据传输。初始化后主机可以改变数据总线的宽度(通过ACMD6命令设置)。7 Z5 q) L2 P, \6 B
% W9 R) a# w( p6 y
如果一个多媒体卡接到了总线上,则SDIO_D0、SDIO_D[3:0]或SDIO_D[7:0]可以用于数据传输。MMC版本V3.31和之前版本的协议只支持1位数据线,所以只能用SDIO_D0(为了通用性考虑,在程序里面我们只要检测到是MMC卡就设置为1位总线数据)。
1 ~) M+ I; ]5 }( g2 H% [1 }4 f8 z5 b8 Y- `$ {# ^/ w, V
如果一个SD或SD I/O卡接到了总线上,可以通过主机配置数据传输使用SDIO_D0或SDIO_D[3:0]。所有的数据线都工作在推挽模式。; b+ G# x: D  ~4 ^

; ~+ N( m/ W% f% a+ PSDIO_CMD有两种操作模式:. |" v- u  V' Y* r9 Q  A) R
/ U) B# E0 a& P2 W* t7 ?
用于初始化时的开路模式(仅用于MMC版本V3.31或之前版本)
- @1 `5 G8 D) i$ h  i4 L" A4 O) c9 t6 S
用于命令传输的推挽模式(SD/SD I/O卡和MMC V4.2在初始化时也使用推挽驱动)% {* R9 M+ z' C. b
1 T# b) T1 ^9 ?% H9 W- j' A
2.      SDIO的时钟
  X- E3 _( ]3 S% w; G从上图我们可以看到SDIO总共有3个时钟,分别是:
0 t' l$ q, E3 ^, b! _0 [# L6 ~# j8 N3 M( X2 ~7 W, V7 {/ x3 x1 H
1)卡时钟(SDIO_CK):每个时钟周期在命令和数据线上传输1位命令或数据。对于多媒体卡V3.31协议,时钟频率可以在0MHz至20MHz间变化;对于多媒体卡V4.0/4.2协议,时钟频率可以在0MHz至48MHz间变化;对于SD或SD I/O卡,时钟频率可以在0MHz至25MHz间变化。
$ S# `# J2 M/ {/ F8 v) B# \5 Q) w0 h; r5 w  L! b' O, R; P
2) SDIO适配器时钟(SDIOCLK):该时钟用于驱动SDIO适配器,来自PLL48CK,一般为48Mhz,并用于产生SDIO_CK时钟。
2 n# q# E4 }4 j. f' w- _
! L6 Q# I! ]! i* E1 \  s5 z3) APB2总线接口时钟(PCLK2):该时钟用于驱动SDIO的APB2总线接口,其频率为HCLK/2,一般为84Mhz。3 y. [- K" ~/ T: W
) F4 ~& P# @1 M* {4 l6 d& a
前面提到,我们的SD卡时钟(SDIO_CK),根据卡的不同,可能有好几个区间,这就涉及到时钟频率的设置,SDIO_CK与SDIOCLK的关系(时钟分频器不旁路时)为:SDIO_CK=SDIOCLK/(2+CLKDIV): S0 R, J6 M' G; V5 x6 P+ m
' T, W' V8 a7 W2 S
其中,SDIOCLK为PLL48CK,一般是48Mhz,而CLKDIV则是分配系数,可以通过SDIO的SDIO_CLKCR寄存器进行设置(确保SDIO_CK不超过卡的最大操作频率)。注意,以上公式,是时钟分频器不旁路时的计算公式,当时钟分频器旁路时,SDIO_CK直接等于SDIOCLK。1 G5 `2 C4 _) h: y: Y
% k% z4 I% G. }9 Y- s% c
这里要提醒大家,在SD卡刚刚初始化的时候,其时钟频率(SDIO_CK)是不能超过400Khz的,否则可能无法完成初始化。在初始化以后,就可以设置时钟频率到最大了(但不可超过SD卡的最大操作时钟频率)。. e0 e  x% Q& P0 M  O

" Y, d1 h& q3 B" r, U3.      SDIO的命令与响应# H- k7 S/ Z3 [9 O0 N4 F
SDIO的命令分为应用相关命 令(ACMD)和 通 用 命 令(CMD)两部分,应用相关命令(ACMD)的发送,必须先发送通用命令(CMD55),然后才能发送应用相关命令(ACMD)。
* X" u1 E/ V# J8 X+ ]; R9 z$ U: S0 b7 G6 ?- l7 Z
SDIO的所有命令和响应都是通过SDIO_CMD引脚传输的,任何命令的长度都是固定为48位,SDIO的命令格式如图所示:; I# A$ i( u4 m0 K7 S( R( c+ b
( F) s. w) K( B; X
2.png

6 X) H' g( {  e  t/ P5 A所有的命令都是由STM32F4发出,其中开始位、传输位、CRC7和结束位由SDIO硬件控制,我们需要设置的就只有命令索引和参数部分。其中命令索引(如CMD0,CMD1之类的)在SDIO_CMD寄存器里面设置,命令参数则由寄存器SDIO_ARG设置。
( e; j6 c! G  g1 N6 _
7 E4 h: x  k: |7 S+ C$ W% E4 N一般情况下,选中的SD卡在接收到命令之后,都会回复一个应答(注意CMD0是无应答的),这个应答我们称之为响应,响应也是在CMD线上串行传输的。STM32F4的SDIO控制器支持2种响应类型,即:短响应(48位)和长响应(136位),这两种响应类型都带CRC错误检测(注意不带CRC的响应应该忽略CRC错误标志,如CMD1的响应)。9 B; Z. A& Y1 l

% r0 S+ L# p2 T( V5 x& d8 q1 u短响应的格式如表所示
# Z- U, J" {" g* J
, R' x# L/ u% a: U
3.png

: d9 j- N; P/ c# L* r长响应的格式如图所示:
2 @& ?+ T. k2 z0 |1 t- c& p( d8 t9 @, m
4.png

, {/ E. m. }" T  S同样,硬件为我们滤除了开始位、传输位、CRC7以及结束位等信息,对于短响应,命令索引存放在SDIO_RESPCMD寄存器,参数则存放在SDIO_RESP1寄存器里面。对于长响应,则仅留CID/CSD位域,存放在SDIO_RESP1~SDIO_RESP4等4个寄存器。/ U8 I( S5 i. S5 ~0 G$ E
1 Q0 k6 ^9 s" U' T" @
SD存储卡总共有5类响应(R1、R2、R3、R6、R7),我们这里以R1为例简单介绍一下。
& K# h8 }( T5 F2 ^6 \2 U
. V& z( K. ~; K- d$ t! wR1(普通响应命令)响应输入短响应,其长度为48位,R1响应的格式如图所示:
' o6 \) ^, Z" J3 Y* v7 d6 i8 ?- p* b8 ^; ?; z! p% D& k6 \
5.png
$ q( I9 u1 J$ x# @
在收到R1响应后,我们可以从SDIO_RESPCMD寄存器和SDIO_RESP1寄存器分别读出命令索引和卡状态信息。
3 l  c% f7 {) M8 a1 c
/ x, P8 n2 ^4 y& G最后,我们看看数据在SDIO控制器与SD卡之间的传输。对于SDI/SDIO存储器,数据是以数据块的形式传输的,而对于MMC卡,数据是以数据块或者数据流的形式传输。本节我们只考虑数据块形式的数据传输。
, d1 E( H1 R& C+ I: `: H" |% c4 ]% s: x% g9 I, J& l# Z
SDIO(多)数据块读操作,如图所示
) R1 |9 }2 @' c  m! ]* {! [
) j! ?, S" R% _: y1 r' ~
6.png
6 z0 g9 e9 W; L7 p! o
从上图,我们可以看出,从机在收到主机相关命令后,开始发送数据块给主机,所有数据块都带有CRC校验值(CRC由SDIO硬件自动处理),单个数据块读的时候,在收到1个数据块以后即可以停止了,不需要发送停止命令(CMD12)。但是多块数据读的时候,SD卡将一直发送数据给主机,直到接到主机发送的STOP命令(CMD12)。/ o3 z7 \& [) I" u: e

! L6 m9 U1 z7 D: SSDIO(多)数据块写操作,如图所示:
: d; o& g% J8 x, `1 f; s" e" ]3 f% }4 H
7.png
5 @  u  S3 M& h, ^
数据块写操作同数据块读操作基本类似,只是数据块写的时候,多了一个繁忙判断,新的数据块必须在SD卡非繁忙的时候发送。这里的繁忙信号由SD卡拉低SDIO_D0,以表示繁忙,SDIO硬件自动控制,不需要我们软件处理。$ S' x' t: m" w' K
( a: V' }* [1 T4 ?) T' m6 B; p
4.      SDIO相关寄存器介绍
3 S, A: l  B: _第一个,我们来看SDIO电源控制寄存器(SDIO_POWER),该寄存器定义如图所示:, Z$ I& k" L. X0 G
9 H3 l) B/ M! N. x- v5 D5 n1 U
8.png
' Y0 W  g6 X5 G5 g/ p2 d3 y$ \( q
该寄存器复位值为0,所以SDIO的电源是关闭的,我们要启用SDIO,第一步就是要设置该寄存器最低2个位均为1,让SDIO上电,开启卡时钟。+ c( P5 y  x' |8 x9 Y4 e

  {: f# Q- o* [第二个,我们看SDIO时钟控制寄存器(SDIO_CLKCR),该寄存器主要用于设置SDIO_CK的分配系数,开关等,并可以设置SDIO的数据位宽,该寄存器的定义如图所示$ }) q7 s8 y4 h3 }  G- J& T

! ^, I" A6 S" m& Z$ o1 f9 t
9.png
  [, U$ N9 E& }" {# K/ Y. L* x; `
上图仅列出了部分我们要用到的位设置,WIDBUS用于设置SDIO总线位宽,正常使用的时候,设置为1,即4位宽度。BYPASS用于设置分频器是否旁路,我们一般要使用分频器,所以这里设置为0,禁止旁路。CLKEN则用于设置是否使能SDIO_CK,我们设置为1。最后,CLKDIV,则用于控制SDIO_CK的分频,一般设置为0,即可得到24Mhz的SDIO_CK频率。. B0 u! a0 A- V
2 E5 K# l. Q' p9 z
第三个,我们要介绍的是SDIO参数制寄存器(SDIO_ARG),该寄存器比较简单,就是一个32位寄存器,用于存储命令参数,不过需要注意的是,必须在写命令之前先写这个参数寄存器!
: p: [0 @( E# W+ a, U* {4 f( Q6 R. R5 T- v; G% d2 x6 u
第四个,我们要介绍的是SDIO命令响应寄存器(SDIO_RESPCMD),该寄存器为32位,但只有低6位有效,比较简单,用于存储最后收到的命令响应中的命令索引。如果传输的命令响应不包含命令索引,则该寄存器的内容不可预知。
& Z+ d$ S( g$ p+ J2 Z3 g, N, P1 J% Q
第五个,我们要介绍的是SDIO响应寄存器组(SDIO_RESP1~SDIO_RESP4),该寄存器组总共由4个32位寄存器组成,用于存放接收到的卡响应部分信息。如果收到短响应,则数据存放在SDIO_RESP1寄存器里面,其他三个寄存器没有用到。而如果收到长响应,则依次存放在SDIO_RESP1~ SDIO_RESP4里面,如表所示:7 @$ E. E) t* R' a1 p5 |9 c5 X

* E  [- Q- ~! [2 s
10.png

/ m; u9 \: I6 `8 v. c% `第七个,我们介绍SDIO命令寄存器(SDIO_CMD),该寄存器各位定义如图43.1.4.3所示:( [/ R8 w3 J* i* T8 G9 p  g
* K: [, |5 a" W5 i
11.png
2 N' r: ^$ i8 t7 p5 w. e; j
图中只列出了部分位的描述,其中低6位为命令索引,也就是我们要发送的命令索引号(比如发送CMD1,其值为1,索引就设置为1)。位[7:6],用于设置等待响应位,用于指示CPSM是否需要等待,以及等待类型等。这里的CPSM,即命令通道状态机。
( }; S; N# o( [8 J. M# }* R6 w
2 i9 o6 C9 o* u' M+ n1 t/ g第八个,我们要介绍的是SDIO数据定时器寄存器(SDIO_DTIMER),该寄存器用于存储以卡总线时钟(SDIO_CK)为周期的数据超时时间,一个计数器将从SDIO_DTIMER寄存器加载数值,并在数据通道状态机(DPSM)进入Wait_R或繁忙状态时进行递减计数,当DPSM处在这些状态时,如果计数器减为0,则设置超时标志。这里的DPSM,即数据通道状态机,类似CPSM。注意:在写入数据控制寄存器,进行数据传输之前,必须先写入该寄存器(SDIO_DTIMER)和数据长度寄存器(SDIO_DLEN)!3 C4 s' h( y, ^" p. p1 V' y7 G2 u& J

3 X8 j' H: O6 l1 B! h) T第九个,我们要介绍的是SDIO数据长度寄存器(SDIO_DLEN),该寄存器低25位有效,用于设置需要传输的数据字节长度。对于块数据传输,该寄存器的数值,必须是数据块长度(通过SDIO_DCTRL设置)的倍数。
- y. r3 j4 f( d8 E2 I# Q. `, d! F) x
第十个,我们要介绍的是SDIO数据控制寄存器(SDIO_DCTRL),该寄存器各位定义如图所示:
# y9 P& T) g: T' x5 \& P7 V& e( b: \# O
12.png

9 x# t" l8 @2 c6 J: f/ `: S该寄存器,用于控制数据通道状态机(DPSM),包括数据传输使能、传输方向、传输模式、DMA使能、数据块长度等信息,都是通过该寄存器设置。我们需要根据自己的实际情况,来配置该寄存器,才可正常实现数据收发。; V( ~- o  w5 |  f  t, w6 g  q9 z; k

& n# J+ x5 a5 ]/ H! |接下来,我们介绍几个位定义十分类似的寄存器,他们是:状态寄存器(SDIO_STA)、清除中断寄存器(SDIO_ICR)和中断屏蔽寄存器(SDIO_MASK),这三个寄存器每个位的定义都相同,只是功能各有不同。所以可以一起介绍,以状态寄存器(SDIO_STA)为例,该寄存器各位定义如图所示:
4 J( o) ?% A! T( ^9 S9 X3 {. s+ A9 P) }8 W/ L6 ?5 Q
13.png
2 Y9 x/ m  Y! n% b
状态寄存器可以用来查询SDIO控制器的当前状态,以便处理各种事务。比如SDIO_STA的位2表示命令响应超时,说明SDIO的命令响应出了问题。我们通过设置SDIO_ICR的位2则可以清除这个超时标志,而设置SDIO_MASK的位2,则可以开启命令响应超时中断,设置为0关闭。其他位我们就不一一介绍了,请大家自行学习。
8 Q2 {. a( w3 Q+ x/ \& U& D. T
  d9 b; X; f7 I1 h, x6 u最后,我们向大家介绍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字节对齐的内存进行操作,否则将导致出错!2 j: ?9 [, }! X7 u' S; S' t0 e

: y% N1 H9 ?* H; r至此,SDIO的相关寄存器介绍,我们就介绍完了。还有几个不常用的寄存器,我们没有介绍  q" ]! B2 ?5 B# H6 Q: C/ W0 T1 _
; d$ O& o; N$ _( S' u1 l+ N0 e

* R: B5 o% O8 i- h4 p; e2 p, P$ N2 k- b/ D3 k
" V7 ]: V+ a. f/ _4 I- u
转载自于中军6 x6 c' W' u* b  a0 n  ]
9 D. G! r% h2 [& ?/ y" r
9 {, G* }7 T8 I, a  [; q' S

# I" \+ Y2 P/ b; H/ [8 v& b  Y4 x2 ?, C: J
/ {% o, {( y9 k
赞 收藏 2 评论0 发布时间:2018-5-29 13:16

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版