本帖最后由 kkhkbb 于 2018-4-27 11:38 编辑 ' x. [- M8 x; c# l2 i6 c
- P8 ], P5 Y' C1 l: c
一、概述
7 V0 K) j- n) Y8 Z S- X% |9 {9 Y 1.SDIO的定义 SDIO在SD标准上定义了一种外设接口。目前,SDIO主要有两类应用——可移动和不可移动。可移动设备作为Palm和Windows Mobile的扩展设备,用来增加蓝牙、照相机、GPS和 802.11b功能。不可移动设备遵循相同的电气标准,但不要求符合物理标准。某些手机内包含通过SDIO连接CPU的802.11芯片。此举将“珍贵”的I/ O管脚资源用于更重要的功能。 蓝牙、照相机、GPS和802.11b设备有专为它们定义的应用规范。这些应用规范与为PCI和USB设备定义的类规范很相像。它们允许任何宿主设备与任意外设“通话”,只要它们都支持应用规范。
6 s& i& z6 L4 B4 N6 ?9 y SDIO和SD卡规范间的一个重要区别是增加了低速标准。SDIO卡只需要SPI和1位SD传输模式。低速卡的目标应用是以最小的硬件开支支持低速I/ O能力。低速卡支持类似调制解调器、条码扫描仪和GPS接受器等应用。对“组合”卡(存储器+ SDIO)而言,全速和4位操作对卡内存储器和SDIO部分都是强制要求的。
6 c0 U3 ~- R i 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。 数据和命令输出使能信号,控制外部双向驱动程序。
5 F* v% a, ]' ?( |5 D6 e8 _7 y
3 Q( s- W" e" O* A" K8 Y' `! z. x
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>/*, Y) P; D9 V" n+ B4 F4 f C
- * Name : main
; z5 Y4 ^* {, S; C - * Description : ---
0 s& l6 }5 `/ c3 D: _; G/ A; t8 {- I" K - * Author : ysloveivy.; B( U7 ^. [3 z
- *
6 H( S9 E4 X7 h' q e$ J0 D - * History
8 L- {* b5 Q0 ]5 r+ s5 V - * --------------------
: N" D% l* b! g. }7 k - * Rev : 0.00 : Z. [2 ^+ V9 ]2 H+ I+ z
- * Date : 12/01/2015 % b& E1 ^/ ^4 O
- *
* J5 x2 W# `' B! t4 P4 p - * create.5 U* w7 k2 q! l" ~5 f. ~' t; ~
- * --------------------
% ^, S2 [" a8 n) b e B1 m - */int main(void); k L5 m6 B, P* \: ~# k
- {! ]( X8 ?' d: G
- int i;7 Q0 Y) d" d0 s* @. A; n
- led.initialize();
0 T6 V) Z2 L1 ]+ ^; I' K - usart4.initialize(115200);' W7 S K! }* t. C) l( n
- usart4.printf("\x0c"); //清屏 * X6 C& \; ]8 N- r) p
- usart4.printf("\033[1;32;40m"); //设置字体终端为绿色4 q6 q4 k2 \8 P5 L8 o$ s9 z, W6 W
- usart4.printf("\r\n\r\nhello! I am iCore3!\r\n\r\n\r\n");
. ~9 f) t9 y1 e6 S' m; E - //判断SD卡是否初始化5 _, t/ K% M& S
- if(SD_Init() != 0){
: o; u) ]- `/ h. ^. L - usart4.printf("SD ERROR!\r\n");6 @8 X8 @2 m! G7 G
- while(1){' ^; b9 b+ g" _, a3 H& [
- for(i = 0;i < 10000000;i++);
# c* e6 Q4 A& I' S - LED_RED_ON;( B+ W. x/ F* s8 Z
- for(i = 0;i < 10000000;i++);& [0 Z8 R$ G! S* J. J
- LED_RED_OFF;; l2 j7 T2 @3 ?/ \
- }5 c2 F& c, a: }! r' u) P8 g* i
- }( t5 Z" u" `# u: P0 m
- //输出SD卡的类型
( w& O L; x- H+ ^( s - switch(SDCardInfo.CardType){</div><div>case SDIO_STD_CAPACITY_SD_CARD_V1_1:1 @ S4 k" Y7 U, m) c" f# T. |
- usart4.printf("SDCardType\t\t:SDIO_STD_CAPACITY_SD_CARD_V1_1\r\n");: V7 X7 g9 Y3 e+ M
- break;" Q$ \$ m. e: U. U# S$ j
- case SDIO_STD_CAPACITY_SD_CARD_V2_0:
9 ]7 |9 E, P2 b) ] - usart4.printf("SDCardType\t\t:SDIO_STD_CAPACITY_SD_CARD_V2_0\r\n");
; x0 V; P& K7 D/ \ - break;- T8 ^" X% k6 u3 \( G( q+ f
- case SDIO_HIGH_CAPACITY_SD_CARD:0 m4 p( M! ^3 ~0 ^1 Q8 b; {" y9 ~
- usart4.printf("SDCardType\t\t:SDIO_HIGH_CAPACITY_SD_CARD\r\n");
' K# u" t* `) ]' S0 F - break;</div><div> case SDIO_MULTIMEDIA_CARD:" O3 W0 q8 T( A8 |+ \
- usart4.printf("SD CardType\t:SDIO_MULTIMEDIA_CARD\r\n");
" r( M1 T( `3 i( \& g9 J9 ^ - break;
" l$ U9 p' |6 m7 t - }
C, _3 x2 G" p0 ]* E - //输出SD卡的参数
1 _# @2 X/ E1 j% l r - usart4.printf("SD CardCapacity\t\t: %dMB\r\n",(unsigned long int)(SDCardInfo.CardCapacity >> 20));
8 p, j7 {5 s9 M: p% s# y - usart4.printf("SDCardBlockSize\t: %dByte\r\n",SDCardInfo.CardBlockSize);% M; Z1 U4 B. k; _+ C& L
- usart4.printf("SD RCA \t\t\t: %d\r\n",SDCardInfo.RCA);" @! d9 H$ I1 y* \
- usart4.printf("SDManufacturerID\t: %d\r\n",SDCardInfo.SD_cid.ManufacturerID);- R! n4 z' u4 Y' B
- while(1){
- u& r& K- U. U/ d" C4 t - for(i = 0;i < 10000000;i++);7 T! D; l( D" s
- LED_GREEN_ON;
( F$ k0 J! o. X) Q' C u - for(i = 0;i < 10000000;i++);
' O1 L& B, ^8 N5 v& N% Z. B1 o - LED_GREEN_OFF;. q* d$ C% [5 T! j2 z
- }
% ~* e6 d9 R0 T. q - }</div>
复制代码2.SDIO配置结构体 - <div> SDIO_InitStructure.SDIO_ClockDiv = SDIO_TRANSFER_CLK_DIV + 2;- A% p' M# _2 ]( m% {2 t
- SDIO_InitStructure.SDIO_ClockEdge = SDIO_ClockEdge_Rising;
9 A! K% P& i5 {/ X5 s - SDIO_InitStructure.SDIO_ClockBypass = SDIO_ClockBypass_Disable;
, w* r! N. H) N& }9 U" u1 M! G( x - SDIO_InitStructure.SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable;$ S e8 F( r0 F. c" s. y' d
- SDIO_InitStructure.SDIO_BusWide = SDIO_BusWide_1b;
0 g, f4 B( L' a5 x# I& c; s1 ^ - SDIO_InitStructure.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable;
" U/ e! h6 L% l) @9 n k - SDIO_Init(&SDIO_InitStructure);: y% v$ p" T4 G* y' Z4 \% K' R
- </div>
复制代码3.SD卡初始化程序 - SD_Error SD_Init(void): l! w) l# o) J# [1 Y4 i! w6 l+ S
- {
0 b- i U) ~/ c) N" I. w- m1 F - __IO SD_Error errorstatus = SD_OK;6 ?. F; G* @1 j* K, s8 I! B
, s5 Q/ @! |3 C$ V7 C; e6 P- NVIC_InitTypeDef NVIC_InitStructure;
+ c" u# C$ E2 m
! C* {/ p8 Z! i1 O- p- F/ w0 Y, i" f, x- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);0 r, c/ }& I U1 Y
- // SDIO Interrupt ENABLE8 O: `; w1 [( |9 I8 | @) ^" d
- NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn;. W' q% X4 g o5 @: I* a; G
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;0 e8 g$ H2 G: O, O# t
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
# Q+ h# |' j4 Q" d$ D* [ - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
, w# P0 R, b8 \% ~ - NVIC_Init(&NVIC_InitStructure);
& G1 |$ C S. p ` - // DMA2 STREAMx Interrupt ENABLE
# n; w% O7 Y* E$ a6 J2 \ - NVIC_InitStructure.NVIC_IRQChannel = SD_SDIO_DMA_IRQn;
- h. U- P5 b7 s5 A7 u0 ` - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
7 b6 H9 t2 |' A$ f& O6 M - NVIC_Init(&NVIC_InitStructure);' ~6 o7 H( d; O' O2 r! j
- /* SDIO Peripheral Low Level Init */
7 T# l4 D+ |5 G6 \8 q! @ N4 \2 O - SD LowLevel Init ();
$ R4 d% O* F1 E# R9 Z5 V5 ?: d - SDIO DeInit();
* j4 |9 K2 a9 D( M: H - errorstaus = SD PowerON();
. e& A6 h4 A* J, g' F* O - if (errorstatus ! = SD_OK)9 a. ~) N6 G1 `+ A0 b) m$ b" E0 R
- {# f" G/ ?. ^' m' N) f
- /*!<CMD Response TimeOut(wait for CMDSENT flag) */; r' ~ s0 J7 z* ^
- return(errorstatus);; s& Q+ w4 l" I
- }
# L2 ^. V1 e- V# u$ {1 u, a8 [2 A - errorstatus = SD InitializeCards(); N& s: @" L4 j; Y5 z! i& V
- if (errorstatus != SD_OK)' I6 a" J9 v# R @) m/ B1 g
- if (errorstatus !=SD_OK)/ r' d' t! o5 t+ b4 Q( ]
- {
2 A, G, h7 i5 x# i) {& ] n - /*!< CMD Response TimeOut (wait for CMDSENT flag) */: r* \% p Z7 e5 W h$ a9 C
- return(errorstatus);) j1 V R" B: v8 l
- }
复制代码五、实验现象 端显示屏上可以看到Micro SD卡的信息,如下图: 图13_2 实验现象显示图 六 、代码包下载
8 \- f5 ]0 J+ R8 `( ~) ]/ ?' E0 B
8 j% D' ]; j1 B+ n8 |7 y: s$ g4 f6 C# X. t, j8 U& z4 V$ {: P
" K2 S, g0 V2 y% Z2 R; S6 y+ ?6 A1 |: P
8 Z8 c+ R# y4 N$ k- ?0 k9 O" h- M9 d P( d, O' \! a
# G, N5 E( t9 Q
0 e8 R( g& |- \/ r8 p5 g* m0 V
2 d N1 |- f4 F4 k% a2 k
# T" g2 G' k M& W* g1 N6 f* A3 Z* f
2 n& X: X1 H5 q( n( X9 N2 l9 P- Z# f' g
C9 k& f! W4 w& i) o( I
C1 B; {8 N' `. n: v" H
7 c. M% ^5 {- r C# ^) b0 p2 Z& ^' g; o p
; h0 B$ A& ^8 X7 E0 I# c! g5 S) J2 t2 X G7 j) q3 C
0 i5 P% y3 k. k. [% ]4 S
1 ~) G! x3 s+ L2 M
7 W% Y- F7 w( d3 B$ R* u1 w, s0 r( z2 }) Q, V9 U
& c4 G5 L" L j- B! _, }: u1 R
7 x2 @+ X5 W% r9 i: I' G [ i6 _* S) ]# {6 H' w
5 k+ m" i$ |% S a6 F
1 N$ Q- A" t$ M+ h2 h
|