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

【stm32f407】SD协议(一)-SDIO

[复制链接]
aimejia 发布时间:2018-5-29 13:16
本帖最后由 aimejia 于 2018-5-29 17:16 编辑 ' f5 A4 K$ U6 Y  ?2 J7 z
; Y5 }9 c% H! @! r, j
SDIO简介
2 `0 N# E' E! z. _
  _+ s) P* L7 X! e4 _$ j1.      SDIO主要功能及框图
  f  E8 Z: {" s9 F5 L4 S: C6 i8 X9 y3 @, ^STM32F4的SDIO控制器支持多媒体卡(MMC卡)、SD存储卡、SD I/O卡和CE-ATA设备等。SDIO的主要功能如下:) X% u: @4 z) E' o, V- C

4 V4 t# U4 L: @% d1)      与多媒体卡系统规格书版本4.2全兼容。支持三种不同的数据总线模式:1位(默认)、4位和8位。
1 r+ \) x9 |) r) ~: w  r5 A+ o6 t/ X3 x6 o/ H$ m8 x
2)      与较早的多媒体卡系统规格版本全兼容(向前兼容)。, B6 |* T+ a. m
' C/ w  M0 ?/ K& X1 x
3)      与SD存储卡规格版本2.0全兼容。
2 ~( H/ \" ]( r- ~1 k* ]- g
8 {( |" `4 ?( d* r+ q4)      与SD I/O卡规格版本2.0全兼容:支持良种不同的数据总线模式:1位(默认)和4位。
- ~7 ~6 ~  G3 y* B  S* G7 [, j5 b6 f& N" m2 q$ i8 U9 {
5)      完全支持CE-ATA功能(与CE-ATA数字协议版本1.1全兼容)。  8位总线模式下数据传输速率可达48MHz(分频器旁路时)。
; k$ h' W# z' r: c, D/ c) b- `& a1 z; s0 r4 I, L& c
6)      数据和命令输出使能信号,用于控制外部双向驱动器。
9 ~+ R2 V+ `/ t' q0 D' G, Z3 E  d( u, I2 P, Y  S3 y
STM32F4的SDIO控制器包含2个部分:SDIO适配器模块和APB2总线接口,其功能框图如图所示  b, |+ v& x& m7 R
; s1 ~" C6 i1 S5 @8 ^1 s+ K2 [& A
1.png
" k" H3 P; d9 r- S
复位后默认情况下SDIO_D0用于数据传输。初始化后主机可以改变数据总线的宽度(通过ACMD6命令设置)。
- n. U' z3 i6 V7 K; N: C# \( v# T
  E1 I8 I; H/ O5 i# U; v& O如果一个多媒体卡接到了总线上,则SDIO_D0、SDIO_D[3:0]或SDIO_D[7:0]可以用于数据传输。MMC版本V3.31和之前版本的协议只支持1位数据线,所以只能用SDIO_D0(为了通用性考虑,在程序里面我们只要检测到是MMC卡就设置为1位总线数据)。
6 U3 ~- x1 p6 ?" M2 F. N' M7 o. g3 N* g. b- i$ j
如果一个SD或SD I/O卡接到了总线上,可以通过主机配置数据传输使用SDIO_D0或SDIO_D[3:0]。所有的数据线都工作在推挽模式。
6 h1 u4 k0 {1 F% a! b5 Q4 E! A" G; t+ z
SDIO_CMD有两种操作模式:
6 f+ Q1 x! _9 L; ?( }3 P$ s% m2 j% J4 @/ n# i( ^% b* Z* j. F  k
用于初始化时的开路模式(仅用于MMC版本V3.31或之前版本)
+ [2 p7 L$ V1 l$ u5 V
3 K4 ?. n& m) c用于命令传输的推挽模式(SD/SD I/O卡和MMC V4.2在初始化时也使用推挽驱动)* ~2 s% Z4 d% T

! _- p  a% @: U1 @9 r( e2.      SDIO的时钟
9 r( B: {4 X; j9 I' d从上图我们可以看到SDIO总共有3个时钟,分别是:3 z' Q+ P. a4 Q5 @( q5 _4 V! c

* o7 S- L! q; m8 s+ m, e' b1)卡时钟(SDIO_CK):每个时钟周期在命令和数据线上传输1位命令或数据。对于多媒体卡V3.31协议,时钟频率可以在0MHz至20MHz间变化;对于多媒体卡V4.0/4.2协议,时钟频率可以在0MHz至48MHz间变化;对于SD或SD I/O卡,时钟频率可以在0MHz至25MHz间变化。; D9 z8 u! p0 |. V  K* e
; A; \% L; H2 t4 O( ]5 d3 V
2) SDIO适配器时钟(SDIOCLK):该时钟用于驱动SDIO适配器,来自PLL48CK,一般为48Mhz,并用于产生SDIO_CK时钟。
( N- U0 n1 X9 I* I9 y- ]" l
9 p: ]0 w, M! ~* m5 u3) APB2总线接口时钟(PCLK2):该时钟用于驱动SDIO的APB2总线接口,其频率为HCLK/2,一般为84Mhz。
! S' H" u& t% F9 s! ?' n* l( o
' Y$ ?: m" y, n" g6 ^前面提到,我们的SD卡时钟(SDIO_CK),根据卡的不同,可能有好几个区间,这就涉及到时钟频率的设置,SDIO_CK与SDIOCLK的关系(时钟分频器不旁路时)为:SDIO_CK=SDIOCLK/(2+CLKDIV). Q0 V+ u3 \7 L/ t# w

. C5 m" ?2 Z6 r; s: G3 i( q3 y其中,SDIOCLK为PLL48CK,一般是48Mhz,而CLKDIV则是分配系数,可以通过SDIO的SDIO_CLKCR寄存器进行设置(确保SDIO_CK不超过卡的最大操作频率)。注意,以上公式,是时钟分频器不旁路时的计算公式,当时钟分频器旁路时,SDIO_CK直接等于SDIOCLK。: @* o2 V- A7 E3 |8 D# B- \( y/ @
' }  L" R9 s7 d) \$ w2 f
这里要提醒大家,在SD卡刚刚初始化的时候,其时钟频率(SDIO_CK)是不能超过400Khz的,否则可能无法完成初始化。在初始化以后,就可以设置时钟频率到最大了(但不可超过SD卡的最大操作时钟频率)。
" v5 Y3 s* Q9 Z# p! j
6 i/ |$ E' v3 E3 d0 \  M  W3.      SDIO的命令与响应" h* X! T. T1 \" r" b  z6 [% y; ~  Z
SDIO的命令分为应用相关命 令(ACMD)和 通 用 命 令(CMD)两部分,应用相关命令(ACMD)的发送,必须先发送通用命令(CMD55),然后才能发送应用相关命令(ACMD)。
% s! j1 r* n! J/ I# a* L7 v: a* I3 t4 u0 d5 y; K& w
SDIO的所有命令和响应都是通过SDIO_CMD引脚传输的,任何命令的长度都是固定为48位,SDIO的命令格式如图所示:! g9 c4 Y# o8 V, i- `4 O

1 }* i% F# h* ]* q4 X5 h7 `, w
2.png
  f1 n: x. a2 n: ^  T' S
所有的命令都是由STM32F4发出,其中开始位、传输位、CRC7和结束位由SDIO硬件控制,我们需要设置的就只有命令索引和参数部分。其中命令索引(如CMD0,CMD1之类的)在SDIO_CMD寄存器里面设置,命令参数则由寄存器SDIO_ARG设置。
, d- G: P7 x6 M9 m& C4 c# y% L  F4 K/ j3 O1 L  ?
一般情况下,选中的SD卡在接收到命令之后,都会回复一个应答(注意CMD0是无应答的),这个应答我们称之为响应,响应也是在CMD线上串行传输的。STM32F4的SDIO控制器支持2种响应类型,即:短响应(48位)和长响应(136位),这两种响应类型都带CRC错误检测(注意不带CRC的响应应该忽略CRC错误标志,如CMD1的响应)。0 h5 z1 f% z, ^7 Q) i
5 q/ u4 H) n6 U  q1 X
短响应的格式如表所示. d- P2 n3 U- O  p
1 s) i, B2 S3 L: F/ k+ C$ z6 e: L8 U2 I
3.png
# @  z$ C6 N$ m: I
长响应的格式如图所示:
7 R+ d( ], ~: u( F( ?. Q! i7 I1 }; S& h( E! T" f9 G
4.png

/ F) R2 \) M$ @同样,硬件为我们滤除了开始位、传输位、CRC7以及结束位等信息,对于短响应,命令索引存放在SDIO_RESPCMD寄存器,参数则存放在SDIO_RESP1寄存器里面。对于长响应,则仅留CID/CSD位域,存放在SDIO_RESP1~SDIO_RESP4等4个寄存器。& _: h3 n' Z$ o3 F  ^
3 p$ w; A+ Q  p1 b+ \( f& `5 q  T  m
SD存储卡总共有5类响应(R1、R2、R3、R6、R7),我们这里以R1为例简单介绍一下。! G) Y2 A/ |1 ~- f0 ^

& |5 k4 K  L; OR1(普通响应命令)响应输入短响应,其长度为48位,R1响应的格式如图所示:
% Q+ A7 K0 q# T$ S2 C6 Y# N
8 ^" u) v4 d/ p
5.png
) `; P  o: _! G
在收到R1响应后,我们可以从SDIO_RESPCMD寄存器和SDIO_RESP1寄存器分别读出命令索引和卡状态信息。" S% ~6 m( F0 E4 h0 ^0 Y+ J
& g  H  [- A5 z5 d6 E# O7 J
最后,我们看看数据在SDIO控制器与SD卡之间的传输。对于SDI/SDIO存储器,数据是以数据块的形式传输的,而对于MMC卡,数据是以数据块或者数据流的形式传输。本节我们只考虑数据块形式的数据传输。6 Z( g# C: ^% A& U4 |- M1 V

+ R% R* B  _8 F( A8 ?1 }SDIO(多)数据块读操作,如图所示
. r5 ]0 G; b& ^9 g4 L/ _0 O4 C6 R
  C# P2 H( {# p% K- [
6.png
4 D1 ]/ f8 p( ]  M) D+ d
从上图,我们可以看出,从机在收到主机相关命令后,开始发送数据块给主机,所有数据块都带有CRC校验值(CRC由SDIO硬件自动处理),单个数据块读的时候,在收到1个数据块以后即可以停止了,不需要发送停止命令(CMD12)。但是多块数据读的时候,SD卡将一直发送数据给主机,直到接到主机发送的STOP命令(CMD12)。- L; }# P: o0 E& t% M& Q
5 q& V) m+ b! C0 Z- \9 Z0 E
SDIO(多)数据块写操作,如图所示:; P3 }1 D- H. A+ q; `6 L1 U7 P7 M
. f8 {3 w6 r, T- }, B5 a
7.png

" [5 h& f) ?7 Y7 g1 K/ |  C0 g5 c数据块写操作同数据块读操作基本类似,只是数据块写的时候,多了一个繁忙判断,新的数据块必须在SD卡非繁忙的时候发送。这里的繁忙信号由SD卡拉低SDIO_D0,以表示繁忙,SDIO硬件自动控制,不需要我们软件处理。5 l( I: X6 v; A+ B3 }6 ]

% {. H# h3 E1 K+ B2 f; f4.      SDIO相关寄存器介绍
" r' j: a/ P, w+ [0 O8 T第一个,我们来看SDIO电源控制寄存器(SDIO_POWER),该寄存器定义如图所示:' t) X" S$ o; z' l

: I5 F8 E) S# o; N& z1 Q7 D
8.png
; O  u+ l5 ]$ R/ v8 s
该寄存器复位值为0,所以SDIO的电源是关闭的,我们要启用SDIO,第一步就是要设置该寄存器最低2个位均为1,让SDIO上电,开启卡时钟。/ T  E4 _# A5 \% N9 o

9 m" v4 u. G% T3 w; N; ]9 g7 n第二个,我们看SDIO时钟控制寄存器(SDIO_CLKCR),该寄存器主要用于设置SDIO_CK的分配系数,开关等,并可以设置SDIO的数据位宽,该寄存器的定义如图所示
( X+ I2 q& m7 V$ s- d  H. ?
9 u8 [! i9 V9 C  Y
9.png

6 `6 _. x( q1 Q+ r1 p上图仅列出了部分我们要用到的位设置,WIDBUS用于设置SDIO总线位宽,正常使用的时候,设置为1,即4位宽度。BYPASS用于设置分频器是否旁路,我们一般要使用分频器,所以这里设置为0,禁止旁路。CLKEN则用于设置是否使能SDIO_CK,我们设置为1。最后,CLKDIV,则用于控制SDIO_CK的分频,一般设置为0,即可得到24Mhz的SDIO_CK频率。4 ^3 f8 f4 b' u% m9 w( m

# b) ~/ [3 J; v/ m$ ^2 u# K- }第三个,我们要介绍的是SDIO参数制寄存器(SDIO_ARG),该寄存器比较简单,就是一个32位寄存器,用于存储命令参数,不过需要注意的是,必须在写命令之前先写这个参数寄存器!
) T1 c( j2 c0 z5 u
) q8 m* J# W; {  o3 E( A* D; {第四个,我们要介绍的是SDIO命令响应寄存器(SDIO_RESPCMD),该寄存器为32位,但只有低6位有效,比较简单,用于存储最后收到的命令响应中的命令索引。如果传输的命令响应不包含命令索引,则该寄存器的内容不可预知。. W1 x) o! |7 n0 J, H7 `1 m/ e3 _2 K
3 R/ ?8 u  [) B5 j. e( Z
第五个,我们要介绍的是SDIO响应寄存器组(SDIO_RESP1~SDIO_RESP4),该寄存器组总共由4个32位寄存器组成,用于存放接收到的卡响应部分信息。如果收到短响应,则数据存放在SDIO_RESP1寄存器里面,其他三个寄存器没有用到。而如果收到长响应,则依次存放在SDIO_RESP1~ SDIO_RESP4里面,如表所示:
, q1 {" f* N. S" i  J* R
: r/ ]4 t6 b- e; n6 p( a2 R. x
10.png
8 t* T6 w( l2 B- W7 P
第七个,我们介绍SDIO命令寄存器(SDIO_CMD),该寄存器各位定义如图43.1.4.3所示:
0 |. B9 f  N6 N% Y
9 _7 X/ z/ I$ @# F6 Y& L& ^
11.png
( V$ B! ?+ A" q5 r9 @& X
图中只列出了部分位的描述,其中低6位为命令索引,也就是我们要发送的命令索引号(比如发送CMD1,其值为1,索引就设置为1)。位[7:6],用于设置等待响应位,用于指示CPSM是否需要等待,以及等待类型等。这里的CPSM,即命令通道状态机。
$ i1 i$ B* U1 i1 Z2 a" c& S
0 S" l/ R! {$ F第八个,我们要介绍的是SDIO数据定时器寄存器(SDIO_DTIMER),该寄存器用于存储以卡总线时钟(SDIO_CK)为周期的数据超时时间,一个计数器将从SDIO_DTIMER寄存器加载数值,并在数据通道状态机(DPSM)进入Wait_R或繁忙状态时进行递减计数,当DPSM处在这些状态时,如果计数器减为0,则设置超时标志。这里的DPSM,即数据通道状态机,类似CPSM。注意:在写入数据控制寄存器,进行数据传输之前,必须先写入该寄存器(SDIO_DTIMER)和数据长度寄存器(SDIO_DLEN)!
" y. c; N0 g/ c: s
* K( T+ O+ n" {9 J  J第九个,我们要介绍的是SDIO数据长度寄存器(SDIO_DLEN),该寄存器低25位有效,用于设置需要传输的数据字节长度。对于块数据传输,该寄存器的数值,必须是数据块长度(通过SDIO_DCTRL设置)的倍数。
; N0 j; p4 @4 Q" J/ g; e* m' K; `
第十个,我们要介绍的是SDIO数据控制寄存器(SDIO_DCTRL),该寄存器各位定义如图所示:
% N5 s$ d8 A$ g- J! c- n. N  z3 |! [% \. y
12.png

$ E) F4 W0 i' O$ r该寄存器,用于控制数据通道状态机(DPSM),包括数据传输使能、传输方向、传输模式、DMA使能、数据块长度等信息,都是通过该寄存器设置。我们需要根据自己的实际情况,来配置该寄存器,才可正常实现数据收发。. j# n4 c( q/ p; |* |

  X5 b) W) g* v. b% v接下来,我们介绍几个位定义十分类似的寄存器,他们是:状态寄存器(SDIO_STA)、清除中断寄存器(SDIO_ICR)和中断屏蔽寄存器(SDIO_MASK),这三个寄存器每个位的定义都相同,只是功能各有不同。所以可以一起介绍,以状态寄存器(SDIO_STA)为例,该寄存器各位定义如图所示:
: p$ h( [8 {( ]- K7 k' `  f. T& M
4 M/ g) \' z$ z/ R9 R
13.png
+ t) G+ X7 ^: V2 Y; o
状态寄存器可以用来查询SDIO控制器的当前状态,以便处理各种事务。比如SDIO_STA的位2表示命令响应超时,说明SDIO的命令响应出了问题。我们通过设置SDIO_ICR的位2则可以清除这个超时标志,而设置SDIO_MASK的位2,则可以开启命令响应超时中断,设置为0关闭。其他位我们就不一一介绍了,请大家自行学习。  a1 M$ j3 S2 S

' p0 p/ p8 }/ a2 {( N6 {) U. W7 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字节对齐的内存进行操作,否则将导致出错!  n) S8 h, v$ @$ f0 _' O* Q
1 Y& @0 r1 u/ I; I! x$ \
至此,SDIO的相关寄存器介绍,我们就介绍完了。还有几个不常用的寄存器,我们没有介绍
' U7 J, Z: T) Z: v6 @- F2 F& {& l  H1 `* l5 Z  ], u! Z4 z. U

+ X1 @. E3 i' b3 [2 v/ F9 `; l) K! X0 I" |! v
6 D$ a8 \/ K+ U* _( K- u/ S
转载自于中军
* {6 t" e# L$ j' c6 o9 X
8 l1 j( P5 H4 t( s& S3 _3 C) K8 [2 C& q8 ^& D  H4 [; ?

$ B0 Z$ {1 ^( C
  z, k# f# [9 h0 I& ?3 E1 G, X# y! Y( ^. f. O
赞 收藏 2 评论0 发布时间:2018-5-29 13:16

举报

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