本帖最后由 kkhkbb 于 2018-4-27 11:38 编辑
" g; C/ L' u9 g; F( C( ~9 P B" I2 E1 v# n# s
一、概述8 d$ M9 a9 N& f
1.SDIO的定义 SDIO在SD标准上定义了一种外设接口。目前,SDIO主要有两类应用——可移动和不可移动。可移动设备作为Palm和Windows Mobile的扩展设备,用来增加蓝牙、照相机、GPS和 802.11b功能。不可移动设备遵循相同的电气标准,但不要求符合物理标准。某些手机内包含通过SDIO连接CPU的802.11芯片。此举将“珍贵”的I/ O管脚资源用于更重要的功能。 蓝牙、照相机、GPS和802.11b设备有专为它们定义的应用规范。这些应用规范与为PCI和USB设备定义的类规范很相像。它们允许任何宿主设备与任意外设“通话”,只要它们都支持应用规范。6 M9 Q2 D' }" H5 S: V7 [8 A4 j
SDIO和SD卡规范间的一个重要区别是增加了低速标准。SDIO卡只需要SPI和1位SD传输模式。低速卡的目标应用是以最小的硬件开支支持低速I/ O能力。低速卡支持类似调制解调器、条码扫描仪和GPS接受器等应用。对“组合”卡(存储器+ SDIO)而言,全速和4位操作对卡内存储器和SDIO部分都是强制要求的。5 F" i; o- ~& d
2.SDIO的功能 转换设备的能力 SD标准有很大的弹性,比方说,SD插槽不仅能插入内存卡。SDIO卡是一种界面,即由使用标准SD卡插槽来扩展设备的功能,让设备拥有新的功能。 新功能列举如下:GPS 相机 Wi-Fi 调频广播 以太网 条形码读卡器 蓝牙; 将与SD memory card同样的终端形状的卡槽利用于扩张卡的规格。把对应SDIO卡槽(插口)称为SDIO卡,扩张卡称为SDIO卡。 是为了在个人电脑和PDA等中添加功能而使用SD卡的规格,由于可以使用比PC卡形状还小的卡和插槽,相比于笔记本电脑,更多采用于小巧的PDA中。主要销售的产品有,面向PDA的PHS通讯卡和蓝牙通讯卡,无线网卡,小型数码相机等。 为了使用SDIO,必须要有对应的插槽,数码相机等memory card的专用缝儿插槽不对应SDIO卡。SDIO插槽中能够插入SD memory card来读写。 SD/SDIO MMC卡主机接口(SDIO)提供APB2外设总线与多媒体卡(MMC)、SD卡、SDIO卡以及CE-ATA设备之间的接口。 3.SDIO具有如下主要特性: 完全兼容多媒体卡系统规范版本4.2。卡支持三种不同数据总线模式:1位(默认)、4位和8位。 完全兼容先前版本的多媒体卡(向前兼容性)。 完全兼容SD存储卡规范版本2.0。 完全兼容SDI/O卡规范版本2.0:卡支持两种不同数据总线模式:1位(默认)和4位。 完全支持CE-ATA功能(完全符合CE-ATA数字协议版本1.1)。 对于8位模式,数据传输高达48MHz。 数据和命令输出使能信号,控制外部双向驱动程序。7 a3 s# \+ }) {3 u, D
C2 }3 i: d) h p
4.SD卡识别过程: 多媒体卡和SD卡的卡识别过程有所不同。对于多媒体,识别过程是以时钟速率开始。SDIO_CMD线输出驱动器是开楼引脚,在此识别过程中允许并行的卡操作。对准过程以如下方式完成: (1)激活总线。 (2)SDIO卡主机广播SEND_OP_COND(CMD1)以接收运行条件。 (3)卡以其运行条件寄存器的内容进行响应。 (4)不兼容的卡将被置于无效状态。 (5)SDIO卡主机向所有有效广播ALL_SEND_CID(CMD2)。 (6)这些卡将发回其唯一的卡识别号(CID)并进入识别状态。 (7)SDIO卡主机向某个地址的有效卡发出SET_RELATIVE_ADDR(CMD3)。这一新地址称为相对卡地址(RCA);它比CID更短,可对卡进行寻址。分配的卡变为待机状态。SDIO卡主机可以重新发出此命令以更改RCA。卡的RCA是最后分配的值。 (8)SDIO卡主机对所有有效卡重复步骤5到7。 二、硬件电路 图13_0 SD卡槽电路图 三、实验原理 STM32F407上带有SDIO控制器,iCore3核心板上将SDIO连接到TF卡座上。本实验将Micro SD卡插入TF卡座上即可。硬件连接示意图如下: 图13_1 实验原理图 四、源代码 1. 主函数 - <div>/*! F9 U% {1 A2 {+ f) v. w8 @
- * Name : main
6 j* c5 A8 T1 H7 n- y/ |: H - * Description : ---
' b1 x t# m# d. O3 ` - * Author : ysloveivy.0 e; q5 E3 C) e& c6 P
- *
. [- X" p; V9 @9 l9 p - * History , M' T% v7 q2 k& h3 `1 o) g# ^" h- h
- * --------------------
( z5 ^0 K1 B& U, W- J" e/ J% } - * Rev : 0.00 ( \9 w% Q6 s. v4 _* g6 c
- * Date : 12/01/2015 3 U: ?1 C$ P' {: A4 |) W
- *
1 |1 j8 H) S! |3 A7 B" H8 h" u - * create.
" W1 @- }$ Z. N$ e% P1 i( D - * -------------------- # D1 L( r9 P. A5 x
- */int main(void)
: v: n8 K; w- N" X* y - {8 i: `; E, o3 ?& S. a- h
- int i;5 y& Y; Z0 ^( {3 S: f
- led.initialize();
; N5 e& v+ L* v9 {- o - usart4.initialize(115200);% r& c0 u3 I" X5 Z& H" J1 m3 w
- usart4.printf("\x0c"); //清屏 " M" Q$ }! \3 x/ F! U! A. j
- usart4.printf("\033[1;32;40m"); //设置字体终端为绿色
; H, ?4 s, T- } - usart4.printf("\r\n\r\nhello! I am iCore3!\r\n\r\n\r\n");
0 w" l1 q% S' t. D - //判断SD卡是否初始化. u/ o+ ]3 I# J, e
- if(SD_Init() != 0){: Z! n, ]1 ^$ o$ _
- usart4.printf("SD ERROR!\r\n");1 l% }/ I+ |; [2 h9 H& ?
- while(1){
" C5 C7 h) Q1 B$ i - for(i = 0;i < 10000000;i++);& q+ m: e- Y, g1 d7 @) M
- LED_RED_ON;3 a$ q# }' V+ Q$ ^
- for(i = 0;i < 10000000;i++);5 Z% H8 o: J. A/ g& k2 h% |# v7 E
- LED_RED_OFF;
3 `4 a% z6 I7 v$ [" D - }! |! s6 q+ s4 K; G/ Y5 ]( ~6 k2 c
- }% M. y/ C: W! E: ]
- //输出SD卡的类型
! D8 u8 v* i/ \7 ~- a7 `: n - switch(SDCardInfo.CardType){</div><div>case SDIO_STD_CAPACITY_SD_CARD_V1_1:
7 o3 n; i2 s- E) r M+ I - usart4.printf("SDCardType\t\t:SDIO_STD_CAPACITY_SD_CARD_V1_1\r\n");
3 x% v/ F Y6 Q% ] - break;' D0 l* n5 K( W# A: y$ ?
- case SDIO_STD_CAPACITY_SD_CARD_V2_0:
2 w. f) A7 r! [% ~8 t1 L - usart4.printf("SDCardType\t\t:SDIO_STD_CAPACITY_SD_CARD_V2_0\r\n");2 v* y! S3 ]9 M3 E. q( J% J, L+ f5 E: w
- break;
2 k$ V" @+ h' c/ Q7 L4 u - case SDIO_HIGH_CAPACITY_SD_CARD:( L4 ^: x, R$ H4 @8 k
- usart4.printf("SDCardType\t\t:SDIO_HIGH_CAPACITY_SD_CARD\r\n");
4 A1 X9 x4 D3 L# o7 Q - break;</div><div> case SDIO_MULTIMEDIA_CARD:* i' M5 h( S8 {9 h2 u
- usart4.printf("SD CardType\t:SDIO_MULTIMEDIA_CARD\r\n");
" s8 c3 n* O: u1 K) I9 n! F - break;) L$ \: _; r0 _, \2 H& r" l1 V
- }5 Z( u6 a) c, v- I3 k7 R3 z" v9 z& ]
- //输出SD卡的参数' [4 l) R' n# I- k; I' H) d
- usart4.printf("SD CardCapacity\t\t: %dMB\r\n",(unsigned long int)(SDCardInfo.CardCapacity >> 20));( i$ l% [. u* z0 K3 P
- usart4.printf("SDCardBlockSize\t: %dByte\r\n",SDCardInfo.CardBlockSize);
& G& x$ `1 E" S' K2 n7 I - usart4.printf("SD RCA \t\t\t: %d\r\n",SDCardInfo.RCA);
+ Z+ u2 V2 H: [ - usart4.printf("SDManufacturerID\t: %d\r\n",SDCardInfo.SD_cid.ManufacturerID);# k' C7 q$ m; @1 y0 T' o: U
- while(1){9 }6 ]; |. K; K+ r. S- l! i
- for(i = 0;i < 10000000;i++);( o$ K2 j8 x# {) y& a
- LED_GREEN_ON;/ |$ ]5 R+ T" n5 k6 E% ]$ V* n
- for(i = 0;i < 10000000;i++);6 n7 J l3 G) j& ], r/ k
- LED_GREEN_OFF;: U! s! K c3 A. U
- }
: `: |, h ?# s% K4 M) | - }</div>
复制代码2.SDIO配置结构体 - <div> SDIO_InitStructure.SDIO_ClockDiv = SDIO_TRANSFER_CLK_DIV + 2;/ a E, n! | |; d! |$ I6 v$ c
- SDIO_InitStructure.SDIO_ClockEdge = SDIO_ClockEdge_Rising;0 p; _) n$ q0 i6 `- s' r
- SDIO_InitStructure.SDIO_ClockBypass = SDIO_ClockBypass_Disable;' M/ Z! ~" c2 m4 N
- SDIO_InitStructure.SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable;4 [0 Y3 Q }( a$ Y- s* Y( v+ n
- SDIO_InitStructure.SDIO_BusWide = SDIO_BusWide_1b;
" L4 P2 _' u- H3 h7 G5 O( _# A; o - SDIO_InitStructure.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable;
' F7 y2 [7 }* D - SDIO_Init(&SDIO_InitStructure);
( c% N6 X$ C1 l8 V - </div>
复制代码3.SD卡初始化程序 - SD_Error SD_Init(void)% |( H7 i) O& d
- {
, K1 q6 k6 N) t) @2 Z+ c8 ~ - __IO SD_Error errorstatus = SD_OK;5 ]% f9 c u L# W( S4 b
: J$ b& @7 U1 ^( m" k- NVIC_InitTypeDef NVIC_InitStructure;. K. m* n8 z0 A
/ T7 F k2 V+ k2 v9 e) t5 R- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
, Z( A3 D+ L& D/ W - // SDIO Interrupt ENABLE' G" J' C' S8 w$ \% u
- NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn;
0 ?4 v$ e# _2 v% b# w9 U, e( Y - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
1 l# F# b/ s& y' W) T% w, E w+ b - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;1 k; ^$ R; k3 f" A
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;$ U4 U; N- z" m8 K L
- NVIC_Init(&NVIC_InitStructure);
8 Y/ w" ^2 M1 w. \6 K! p1 x% @/ k - // DMA2 STREAMx Interrupt ENABLE
. y$ ?$ D$ C& H8 v - NVIC_InitStructure.NVIC_IRQChannel = SD_SDIO_DMA_IRQn;. v$ [+ n* @) B; V n4 b7 c* n, ~
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
# X% o! R4 \% g( N8 L5 b - NVIC_Init(&NVIC_InitStructure);4 ^/ T/ D( S9 N) Z
- /* SDIO Peripheral Low Level Init */9 v' z/ I/ P5 |; I, N& M3 D
- SD LowLevel Init ();; ?) t A B8 L1 N2 {6 O
- SDIO DeInit();
I4 c, V4 A$ x3 W+ z6 d - errorstaus = SD PowerON();8 Z$ h$ `! l0 ^) ?) ~
- if (errorstatus ! = SD_OK)
0 z3 N" i! T% ]6 D. ~ S% r - {- v! u; N) n1 Y2 [) W f
- /*!<CMD Response TimeOut(wait for CMDSENT flag) */
( u7 B1 y, B0 D o - return(errorstatus);+ b/ [+ g; L7 L+ a* N0 [: u' U
- }
( Q0 P1 X) {' M" S1 R - errorstatus = SD InitializeCards();% x) R; o4 p! N
- if (errorstatus != SD_OK)
?$ v) P2 L/ b - if (errorstatus !=SD_OK)
+ T0 P+ X2 Y( v: P% u - {
3 J, J+ T8 [. s0 f4 z5 | - /*!< CMD Response TimeOut (wait for CMDSENT flag) */: r" ]1 s- L H) X! t9 f+ G
- return(errorstatus);
, V; X: G) Z" e. }, q. u2 q/ Y - }
复制代码五、实验现象 端显示屏上可以看到Micro SD卡的信息,如下图: 图13_2 实验现象显示图 六 、代码包下载
/ V5 `* c2 @3 _/ r ! g8 A* M. G& i- M$ t1 z; ^- N
" ?: l' v0 Y6 J+ q3 \# g4 \
O% y; i4 q* R3 d- Q" }' {) M/ r- h4 x& p3 H6 N" y
# Z% U# J$ K1 d% @
) A# K- C. [' H" O1 G7 m# ~
. v9 g$ u7 |: C% b' x6 d R& }' E5 f1 ~ $ h+ U% i r. ?
) l p: I& ]! q; B
+ B4 G, h2 G7 I/ L: t
# s1 Y3 k: R/ h8 i4 `4 `6 Q- r
4 R" a( R; {( u
% Q( |( F0 s* j; j
, n! X, p2 r) ?, g4 p+ R
* }( e2 h1 L$ _# J4 [# n: _
; ^+ Y& i3 X1 O4 s: ~ L- {: q& }/ \" i* p; \- A" I: L# j
" v. A, t' e V
( ` l5 T. J ~! K$ U
7 H2 O1 S& A+ D* u! U
; y0 y# c7 s3 [: P$ a
' p( z: O) d# E+ ?3 h {
+ }( E" Z* T9 h! t- [
0 [4 h+ g4 t! R {3 P9 ~1 [; t5 Y4 \$ b! D+ \
, y* O2 N. u1 m! H
# z4 z; _7 I5 s
& X! X) u0 H. z' u |