本帖最后由 kkhkbb 于 2018-4-27 11:38 编辑 ' N8 P4 ^" @3 i8 y
3 f- i+ D9 x8 u) d4 r一、概述: c8 E# I1 ]# N" y }. ?* I k
1.SDIO的定义 SDIO在SD标准上定义了一种外设接口。目前,SDIO主要有两类应用——可移动和不可移动。可移动设备作为Palm和Windows Mobile的扩展设备,用来增加蓝牙、照相机、GPS和 802.11b功能。不可移动设备遵循相同的电气标准,但不要求符合物理标准。某些手机内包含通过SDIO连接CPU的802.11芯片。此举将“珍贵”的I/ O管脚资源用于更重要的功能。 蓝牙、照相机、GPS和802.11b设备有专为它们定义的应用规范。这些应用规范与为PCI和USB设备定义的类规范很相像。它们允许任何宿主设备与任意外设“通话”,只要它们都支持应用规范。
) ? D5 L( K. q SDIO和SD卡规范间的一个重要区别是增加了低速标准。SDIO卡只需要SPI和1位SD传输模式。低速卡的目标应用是以最小的硬件开支支持低速I/ O能力。低速卡支持类似调制解调器、条码扫描仪和GPS接受器等应用。对“组合”卡(存储器+ SDIO)而言,全速和4位操作对卡内存储器和SDIO部分都是强制要求的。% m8 T/ u d9 Q. Y1 R
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。 数据和命令输出使能信号,控制外部双向驱动程序。; Y: p) X3 m% B4 k
* F! F9 X( k5 }* @9 O# Q' M7 g* l
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>/*
. t) a& |3 O$ V: r6 I, h$ A - * Name : main ' v' _, R# K% u( l2 O0 i( U) E
- * Description : --- $ C. n/ }5 `, @
- * Author : ysloveivy.
0 k- I$ _ m; {/ S0 s - *
& [) h$ M1 D& P+ l# ~ - * History . l( i5 i: c' _. _5 ~
- * --------------------
) ~- m" v6 ~& P% p6 y" f/ R - * Rev : 0.00 + l7 G9 e0 l# s9 a
- * Date : 12/01/2015 * `0 F) {# ]# ?6 {! ^# h' K0 q
- * & s& L! \# q4 Y, E/ U+ s+ s$ w/ G
- * create.
. D3 T9 q2 H9 N7 x9 c - * --------------------
, u" q F$ z- o - */int main(void). v2 B* n- i, D/ u; M9 F0 m% n, u
- { l$ k/ w) @4 Q2 s% l9 U/ w0 w
- int i;
4 j: z' ?( Q7 N! N* y - led.initialize();$ X& d4 I T1 j, ?
- usart4.initialize(115200);% a) a4 J- D; x4 I
- usart4.printf("\x0c"); //清屏 3 J* y) u( K3 V/ [0 _- }
- usart4.printf("\033[1;32;40m"); //设置字体终端为绿色
, [ ~% ~* e" A* S1 @+ l: P - usart4.printf("\r\n\r\nhello! I am iCore3!\r\n\r\n\r\n");
# j$ E+ Y! X5 g - //判断SD卡是否初始化
( k0 y& | o. {- J v - if(SD_Init() != 0){
- n5 b) Y/ i4 N8 [ - usart4.printf("SD ERROR!\r\n");' w2 Q/ a7 ^9 _) q
- while(1){4 ? d j: ? |8 X# j% y
- for(i = 0;i < 10000000;i++);
, E! R# f* I4 a, I2 K - LED_RED_ON;
. _# N1 x+ q. k' x - for(i = 0;i < 10000000;i++);
& M! N- c1 ^+ P9 D5 c - LED_RED_OFF;) Z1 ^; J8 e% H7 v0 K- _6 ]; N
- } X) V# g$ e P% x, Z% {
- }; q. v" m( F1 j) S4 ^ W# y
- //输出SD卡的类型4 H3 G- U; Q4 F& [/ o6 T, @. C
- switch(SDCardInfo.CardType){</div><div>case SDIO_STD_CAPACITY_SD_CARD_V1_1:
5 c9 S. V; l% q; g- B4 o - usart4.printf("SDCardType\t\t:SDIO_STD_CAPACITY_SD_CARD_V1_1\r\n");
* `1 O+ N2 o0 s - break;( B' W1 o+ i* b u( e+ B
- case SDIO_STD_CAPACITY_SD_CARD_V2_0:( S& j* j ~$ e
- usart4.printf("SDCardType\t\t:SDIO_STD_CAPACITY_SD_CARD_V2_0\r\n");: K3 d/ s: l4 Q% k% }+ W! C
- break;) c0 |8 U9 w% x$ f
- case SDIO_HIGH_CAPACITY_SD_CARD:$ G" r+ X6 J( M
- usart4.printf("SDCardType\t\t:SDIO_HIGH_CAPACITY_SD_CARD\r\n");
2 M ?2 ^5 V. A0 a n - break;</div><div> case SDIO_MULTIMEDIA_CARD:6 m( a2 t7 o- c
- usart4.printf("SD CardType\t:SDIO_MULTIMEDIA_CARD\r\n");
% X$ L# u @0 {; _) Y: J! i - break;
% L$ p/ l4 V( o3 g! m - }
0 [+ S0 S6 B; i8 q1 b( L7 B! t - //输出SD卡的参数
' d' I; J2 h+ @ - usart4.printf("SD CardCapacity\t\t: %dMB\r\n",(unsigned long int)(SDCardInfo.CardCapacity >> 20));& C9 {( R+ q6 Y
- usart4.printf("SDCardBlockSize\t: %dByte\r\n",SDCardInfo.CardBlockSize);
( U1 t( a3 ?- b# i( V) s - usart4.printf("SD RCA \t\t\t: %d\r\n",SDCardInfo.RCA);' f0 [! H: |. }5 s d, g- Q9 U
- usart4.printf("SDManufacturerID\t: %d\r\n",SDCardInfo.SD_cid.ManufacturerID);
' S, O$ I$ Z; D* h) ?+ U - while(1){
& f9 G5 @8 e# a( o - for(i = 0;i < 10000000;i++);/ G1 r: N' j3 W7 d
- LED_GREEN_ON;0 I6 _* q0 Q k
- for(i = 0;i < 10000000;i++);* Q6 ?' l9 m5 g) d ?6 W7 n) ^# W( X2 H A
- LED_GREEN_OFF;
+ q3 @4 W+ o! g* U7 J0 ^ - }; J K6 b9 t) B
- }</div>
复制代码2.SDIO配置结构体 - <div> SDIO_InitStructure.SDIO_ClockDiv = SDIO_TRANSFER_CLK_DIV + 2;# Q! a- V/ w: ~' R9 C2 c. H& n
- SDIO_InitStructure.SDIO_ClockEdge = SDIO_ClockEdge_Rising;
. b5 k, S# n" \6 l) e# M - SDIO_InitStructure.SDIO_ClockBypass = SDIO_ClockBypass_Disable;1 j: |. N& S9 D7 A
- SDIO_InitStructure.SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable;: e4 }- j3 a- ^! g: @: A2 G
- SDIO_InitStructure.SDIO_BusWide = SDIO_BusWide_1b;. Y2 E6 [$ t% R6 b
- SDIO_InitStructure.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable;
n; p, h* Z7 |$ ] - SDIO_Init(&SDIO_InitStructure);
) k" ?8 O% j" p! d8 N% e- l - </div>
复制代码3.SD卡初始化程序 - SD_Error SD_Init(void)
/ f) Z7 \, h8 f/ K$ {( h9 C/ C - {
" U* E+ f5 [ s2 H - __IO SD_Error errorstatus = SD_OK;8 Y( B4 A- N @- b) l
( X! a2 J% u4 G/ u- NVIC_InitTypeDef NVIC_InitStructure;% M8 H8 C M0 q
$ s7 A v+ \7 o- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
3 j$ v# ^ ~4 N; r- B! x a - // SDIO Interrupt ENABLE& N0 P" x$ C, R% m6 B$ t
- NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn;
/ q4 b/ W9 Y/ j - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
7 |! ?/ I. m X% f( d - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
# G. x, r J. _ - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;5 A" W: i3 A& n- D1 I
- NVIC_Init(&NVIC_InitStructure);
& U2 y: U+ c3 V7 } - // DMA2 STREAMx Interrupt ENABLE G' U$ K, @$ K5 S8 R
- NVIC_InitStructure.NVIC_IRQChannel = SD_SDIO_DMA_IRQn;
& a) v# G1 ] i5 g/ T - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; z" w5 T; T7 P X
- NVIC_Init(&NVIC_InitStructure);
' o0 w5 b7 T! g5 r - /* SDIO Peripheral Low Level Init */
2 E! w* Y. U& x+ L8 a - SD LowLevel Init ();
2 I4 } W. ~5 l/ ^6 J/ T! \ - SDIO DeInit();
$ w Y" K- c; n4 ], A0 k/ W9 Z( K$ C - errorstaus = SD PowerON();8 h$ H+ t# B- g
- if (errorstatus ! = SD_OK)* j3 k( }+ {# J
- {# ]- ]9 M+ f% j, f7 I' ]/ s
- /*!<CMD Response TimeOut(wait for CMDSENT flag) */
7 x, E8 ^& p3 T - return(errorstatus);/ @) r# B# P5 j4 b" s$ b5 X
- }7 g6 p- a8 F6 \8 e4 n8 v
- errorstatus = SD InitializeCards();
, z+ d6 W9 K+ } - if (errorstatus != SD_OK)
3 v- y" z4 D* g* q - if (errorstatus !=SD_OK)) H( x$ @: ~4 y
- {
3 Z9 ?( v) W4 D* k) H6 Y - /*!< CMD Response TimeOut (wait for CMDSENT flag) */
$ E9 f4 N/ P/ ]* K - return(errorstatus);
& X9 M* {5 H+ {$ T2 a - }
复制代码五、实验现象 端显示屏上可以看到Micro SD卡的信息,如下图: 图13_2 实验现象显示图 六 、代码包下载 ( }4 N' m' Q- A
( {6 V. d. U q6 v S1 ?5 ^: @! l# w0 {8 ?
v4 H" m3 I, [: Q4 o
+ s8 z7 h- [ K* k# O4 v U5 R& K# K% H9 T w' Q( o. u! Q
) g& p8 z" P" h" X- S! q' G! K/ V# x7 Q/ M3 `8 X
5 B e& ?4 y8 A( T7 P0 ]7 s1 T: N) B* S& S6 R
8 B: ~' V0 h" J% |
- o0 D4 I: K* g2 t1 i
. j9 _6 A( k- g) y/ g, Y
5 K% a z, t0 O9 K
- Z- W6 Z' \$ g# |8 v( ~' }/ S
% K- `( [# X N% H6 H( Y0 I) l+ \
' ^( z. L2 n; `2 T- d
" Z- ?6 c$ M _2 c! I9 @9 Q6 ~ z4 C) v: H
- U* A( C+ J: ^. }' E& q. g: I7 i6 D5 G: v* `$ \! r% E3 W1 s
9 l6 I8 }9 f9 J% _
/ d. Y8 Z# i& r5 r+ Y) J: \" L% i/ P+ @# W' @/ u6 ^( v. V
* p m4 U" `" `; @4 o7 s) l2 T# p/ V G! K" _$ M
5 c5 Z2 e+ }* U9 | : z/ p0 B7 V! l3 @
+ L& W3 m) B. [8 a R |