手机外屏裂痕贴膜管用摔碎了有几道裂痕,怎么修

Flash芯片接口转SDIO接口 - 总线技术|接口技术 -
中国电子技术论坛 -
最好最受欢迎电子论坛!
后使用快捷导航没有帐号?
Hot [直播]
Flash芯片接口转SDIO接口
14:55:22  
本人想找到一块IC,能够实现主控和Flash芯片间的SDIO通信,但在百度和谷歌中搜了没有搜到,所以才想请各位大哥大姐帮忙,先谢过了。
21:03:50  
表示没听过这种玩法的,但是还是帮顶一下,知道的大哥大姐帮下忙吧
3个问题&&&&&&&&496个浏览
22个问题&&&&&&&&15135个浏览
21个问题&&&&&&&&25079个浏览
Powered by5626人阅读
WinCE6.0&&FL2440(14)
SDIO卡是在SD内存卡接口的基础上发展起来的接口,SDIO接口兼容以前的SD内存卡,并且可以连接SDIO接口的设备,目前根据SDIO协议的SPEC,SDIO接口支持的设备总类有蓝牙,网卡,电视卡等。
&& & & SDIO协议是由SD卡的协议演化升级而来的,很多地方保留了SD卡的读写协议,同时SDIO协议又在SD卡协议之上添加了CMD52和CMD53命令。由于这个,SDIO和SD卡规范间的一个重要区别是增加了低速标准,低速卡的目标应用是以最小的硬件开始来支持低速I/O能力。低速卡支持类似调制解调器,条形码扫描仪和GPS接收器等应用。高速卡支持网卡,电视卡还有&组合&卡等,组合卡指的是存储器+SDIO。
&& & & SDIO和SD卡的SPEC间的又一个重要区别是增加了低速标准。SDIO卡只需要SPI和1位SD传输模式。低速卡的目标应用是以最小的硬件开支来支持低速I/O能力,低速卡支持类似MODEM,条形扫描仪和GPS接收器等应用。对组合卡来说,全速和4BIT操作对卡内存储器和SDIO部分都是强制要求的。
&& & & 在非组合卡的SDIO设备里,其最高速度要只有达到25M,而组合卡的最高速度同SD卡的最高速度一样,要高于25M。
&& & & SDIO总线和USB总线类似,SDIO总线也有两端,其中一端是主机(HOST)端,另一端是设备端(DEVICE),采用HOST- DEVICE这样的设计是为了简化DEVICE的设计,所有的通信都是由HOST端发出命令开始的。在DEVICE端只要能解溪HOST的命令,就可以同HOST进行通信了。
&& & & SDIO的HOST可以连接多个DEVICE,如下图所示:
&& & & 这个是同SD的总线一样的,其中有如下的几种信号
1. & & & CLK信号:HOST给DEVICE的时钟信号.
2. & & & CMD信号:双向的信号,用于传送命令和反应。
3. & & & DAT0-DAT3 信号:四条用于传送的数据线。
4. & & & VDD信号:电源信号。
5. & & & VSS1,VSS2:电源地信号。
在SDIO总线定义中,DAT1信号线复用为中断线。在SDIO的1BIT模式下DAT0用来传输数据,DAT1用作中断线。在SDIO的4BIT模式下DAT0-DAT3用来传输数据,其中DAT1复用作中断线。
SDIO命令:
&& & & SDIO总线上都是HOST端发起请求,然后DEVICE端回应请求。其中请求和回应中会数据信息。
1. & & & Command:用于开始传输的命令,是由HOST端发往DEVICE端的。其中命令是通过CMD信号线传送的。
2. & & & Response:回应是DEVICE返回的HOST的命令,作为Command的回应。也是通过
CMD线传送的。
3. & & & Data:数据是双向的传送的。可以设置为1线模式,也可以设置为4线模式。数据是通过DAT0-DAT3信号线传输的。
  SDIO的每次操作都是由HOST在CMD线上发起一个CMD,对于有的CMD,DEVICE需要返回Response,有的则不需要。
&& & & 对于读命令,首先HOST会向DEVICE发送命令,紧接着DEVICE会返回一个握手信号,此时,当HOST收到回应的握手信号后,会将数据放在4位的数据线上,在传送数据的同时会跟随着CRC校验码。当整个读传送完毕后,HOST会再次发送一个命令,通知DEVICE操作完毕,DEVICE同时会返回一个响应。
&& & & 对于写命令,首先HOST会向DEVICE发送命令,紧接着DEVICE会返回一个握手信号,此时,当HOST收到回应的握手信号后,会将数据放在4位的数据线上,在传送数据的同时会跟随着CRC校验码。当整个写传送完毕后,HOST会再次发送一个命令,通知DEVICE操作完毕,DEVICE同时会返回一个响应。
SDIO的寄存器:
&& & &SDIO卡的设备驱动80%的任务就是操作SDIO卡上的有关寄存器。SDIO卡最多允许有7个功能(function),这个同其功能号是对应的(0~7),每个功能都对应一个128K字节大小的寄存器,这个见下面的图。功能号之所以取值范围是1~7,而没有包含0,是因为功能0并不代表真正的功能,而代表CIA寄存器,即Common I/O Area,这个纪录着SDIO卡的一些基本信息和特性,并且可以改写这些寄存器。其中地址0xfff是SDIO卡的CIS区域,就是基本信息区域,Common Information Structure。初始化的时候读取并配对SDIO设备。
&& & & 这些寄存器的详细分区已经其对应的功能,在开发过程中都是需要仔细研读的,这些都在协议的SPEC中都有详细说明,这里就不在罗索了。
基于ARM含SD控制器的SD卡的SDIO模式驱动解析
SD卡由日本松下、东芝及美国SanDisk公司于1999年8月共同开发研制。
SD卡的结构能保证数字文件传送的安全性,也很容易重新格式化,因此越来越多的被应用的嵌入式系统中。SD卡的使用非常方便,常见的有两种工作模式:SPI和SDIO。SPI是串行的工作模式,速度相对较低,但是使用方便,只要MCU含有SPI接口均可使用。SDIO模式,可以最多4线传输,因此速度比较快,由于SD卡的普及,越来越多的MCU内部集成了SDIO控制器,简化了我们的工作。本文以三星s3c2410为例介绍。
2. & &SD卡的协议
SD卡的控制指令非常强大,支持SPI,SDIO模式,兼容MMC等。而且不同的
指令有不同的响应(3种),这在我们使用指令是要注意的。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:146893次
积分:1972
积分:1972
排名:第19219名
原创:13篇
转载:140篇
评论:14条
(3)(1)(1)(2)(5)(1)(1)(1)(4)(10)(17)(11)(5)(9)(13)(4)(8)(19)(22)(5)(11)您所在位置: &
&nbsp&&nbsp&nbsp&&nbsp
SDIO接口的硬件实现及性能评估.pdf 55页
本文档一共被下载:
次 ,您可全文免费在线阅读后下载本文档。
下载提示
1.本站不保证该用户上传的文档完整性,不预览、不比对内容而直接下载产生的反悔问题本站不予受理。
2.该文档所得收入(下载+内容+预览三)归上传者、原创者。
3.登录后可充值,立即自动返金币,充值渠道很便利
需要金币:180 &&
SDIO接口的硬件实现及性能评估.pdf
你可能关注的文档:
··········
··········
--------------------------Page1------------------------------摘要摘要随着移动手持设备功能的不断增加,在设计专用系统芯片时,为满足用户对新功能的要求,芯片要不断增加新的功能模块。从设计、制造周期和成本方面考虑,在芯片上增加功能扩展接口来实现新功能也是一种好的解决方案。本文介绍的是一种极具发展前景的功能扩展接广|——安全数字输入,输出(SDIO)接口。本文首先介绍了SDIO控制器的设计需求,包括SDIO的命令与数据流格式、重要命令和SDIO卡内部存储区的结构。阐述了SDIO控制器的硬件设计方案,硬件包括命令控制器、数据控制器、中断控制器与时钟功耗控制器四个主要部分,具体论述了上述各模块的主要功能和实现方法。实现了SDIO控制器软件驱动,包括命令控制与数据传输驱动、对即插即用的支持和文件系统。建立了基于ARMulator的高层模型,通过高层模型仿真,评估了SDIO控制器FIFO的性能和参数。最后本文详细验证了SDIO设计,采用基于覆盖率驱动的受限随机验证方法全面验证器。和7461.06Kbyte/s。关键词:系统芯片,SDIO接口,设计,评估,验证--------------------------Page2------------------------------东南大学硕士学位论文AbstractWiththeofmobilefunctionmodulesshouMbeaddeddevelopmentequipment,newtotheSOCtotheneedofittakesatimetochipssatisfycustomers.HoweveLlongtOaddtheofthenewfunctionmodules.Soit'saideaaccomplishdesigngoodfunction—extensioninterfacetotheinterfaceissuchakindoffunction—chip.SDIOextensioninterface.theofSDIOcontrollerisincludesFirstly,thespecificationintroduced,whichandtheconstructionofSDIOcommandanddatacommandsformat,importantregisteriscouldbehardwareofSDIOhostcontrollerdevice.Thendesignproposed,whichintofourcontroller,datacontroller,partitionedparts:commandcontroller,interruptclockanddetailinformationisdescribedinthiscontroller,thepowercommandanddataandFATl6filesystem,architecture,includingtransfer,plug-and—playsimulationmodelbasedonISSisalsointroduced.Ahigh-levelisusedtOevaluateSDIOhostcontrollerandFIFOperformanceparameter.ToguranteehostEliteverificationtoolandFPGAthecorrectnessofSDIOcontroller.SpecmanareusedtOit.verificationverifysystemisdemonstratesthatfunctionofSDIOhostcontrollerFPGAverificationwithSDIO1.01.Theofread—transmissionbetweenhostcompatiablespecspeedandSDcardisandthatofiscontrollermemory8116.98Kbyte/s7461.06Kbyte/s.Keyword:systemchip,SDIOn--------------------------Page3------------------------------东南大学学位论文独创性声明本人声明所呈交的学位论文是我个人在导师指导下进行的研究工作及取得的研究成果。尽我所知,除了文中特别加以标注和致谢的地方外,论文巾不包含其他人已经发表或撰写过的研究成果,也不包含为获得东南大学或其它教育机构的学位或证书而使用过的材料。与我一同工作的同志对本研究所做的任何贡献均已在论文中作了明确的说明并表示了谢意。研究生签名:!肆起日期:珥东南大学学位论文使用
正在加载中,请稍后...2625人阅读
十分不错的文章,简明扼要地介绍了如何初始化SDIO card和读写block!
值得收藏和学习!
MicroSD卡(SDIO模式)测试实验,采用4bit数据线模式。没有跑文件系统,只是单纯地读block并将测试信息通过串口1在电脑的超级终端上 打印出来。
PC12-SDIO-CLK:CLK PC10-SDIO-D2 :DATA2 PC11-SDIO-D3:CD/DATA3PD2-SDIO-CMD :CMDPC8-SDIO-D0:DATA0 PC9-SDIO-D1:DATA1
用到的库文件
startup/start_stm32f10x_hd.c
CMSIS/core_cm3.c
CMSIS/system_stm32f10x.c
FWlib/stm32f10x_gpio.c
FWlib/stm32f10x_rcc.c&
FWlib/stm32f10x_usart.c
FWlib/stm32f10x_sdio.c
FWlib/stm32f10x_dma.c
FWlib/misc.c
用户编写的文件
USER/main.c
USER/stm32f10x_it.c
USER/usart1.c
USER/ sdio_sdcard.c
野火STM32开发板 MicroSD卡硬件原理图:
  1.2 SDIO简介
野火STM32开发板的CPU ( STM32F103VET6 )具有一个SDIO接口。SD/SDIO/MMC主机接口可以支持MMC卡系统规范4.2版中的3个不同的数据总线模式:1位(默认)、4位和8位。在8位模式下,该接口可以使数据传输速率达到48MHz,该接口兼容SD存储卡规范2.0版。SDIO存储卡规范2.0版支持两种数据总线模式:1位(默认)和4位。
目前的芯片版本只能一次支持一个SD/SDIO/MMC 4.2版的卡,但可以同时支持多个MMC 4.1版或之前版本的卡。除了SD/SDIO/MMC,这个接口完全与CE-ATA数字协议版本1.1兼容。
   1.3 SD协议
大多数人原来没有了解过SD协议,又看到SDIO的驱动有2000多行,感觉无从下手。所以野火重新写了这个文档进行详细的解释,帮助大家更快地跨过这道槛。
附资料:《Simplified_Physical_Layer_Spec.pdf》,这个资料包含了SDIO协议中SD存储卡的部分。
下面野火结合STM32的SDIO,分析SD协议,让大家对它先有个大概了解,更具体的说明在代码中展开。
  SDIO接口图
 一.从SDIO的时钟说起。
SDIO_CK时钟是通过PC12引脚连接到SD卡的,是SDIO接口与SD卡用于同步的时钟。
SDIO选配器挂载到AHB总线上,通过HCLK二分频输入到适配器得到SDIO_CK的时钟,这时SDIO_CK = HCLK/(2+CLKDIV)。其中CLKDIV是SDIO_CLK(寄存器)中的CLKDIV位。
另外,SDIO_CK也可以由SDIOCLK通过设置bypass模式直接得到,这时SDIO_CK = SDIOCLK=HCLK。
通过下面的库函数来配置时钟:
SDIO_Init(&SDIO_InitStructure);
对SD卡的操作一般是大吞吐量的数据传输,所以采用DMA来提高效率,SDIO采用的是DMA2中的通道4。在数据传输的时候SDIO可向DMA发出请求。
二.讲解SDIO的命令、数据传输方式。
SDIO的所有命令及命令响应,都是通过SDIO-CMD引脚来传输的。
命令只能由host即STM32的SDIO控制器发出。SDIO协议把命令分成了11种,包括基本命令,读写命令还有ACMD系列命令等。其中,在发送ACMD命令前,要先向卡发送编号为CMD55的命令。
参照下面的命令格式图,其中的start bit,transmission bit ,crc7,endbit,都是由STM32中的SDIO硬件完成,我们在软件上配置的时候只需要设置command
index和命令参数argument。Command index就是命令索引(编号),如CMD0,CMD1…被编号成0,1...。有的命令会包含参数,读命令的地址参数等,这个参数被存放在argument段。
  SD卡命令格式
可以通过下面的函数来配置、发送命令:
SDIO_SendCommand(&SDIO_CmdInitStructure);&&&//发送命令
SD卡对host的各种命令的回复称为响应,除了CMD0命令外,SD卡在接收到命令都会返回一个响应。对于不同的命令,会有不同的响应格式,共7种,分为长响应型(136bit)和短响应型(48bit)。以下图,响应6(R6)为例:
  SD卡命令响应格式(R6)
SDIO通过CMD接收到响应后,硬件去除头尾的信息,把command index&保存到SDIO_RESPCMD寄存器,把argument
field内容保存存储到SDIO_RESPx寄存器中。这两个值可以分别通过下面的库函数得到。
SDIO_GetCommandResponse(); &//卡返回接收到的命令
SDIO_GetResponse(SDIO_RESP1);&//卡返回的argument field内容
数据写入,读取。请看下面的写数据时序图,在软件上,我们要处理的只是读忙。另外,我们的实验中用的是Micro SD卡,有4条数据线,默认的时候SDIO采用1条数据线的传输方式,更改为4条数据线模式要通过向卡发送命令来更改。
   SD卡的多块写入时序图
三.卡的种类。
STM32的SDIO支持SD存储卡,SD I/O卡 ,MMC卡。
其中SDI/O卡与SD存储卡是有区别的,SDI/O卡实际上就是利用SDIO接口的一些模块,插入SD的插槽中,扩展设备的功能,如:SDI/O wifi, SDI/O cmos相机等。而SD存储卡就是我们平时常见的单纯用于存储数据的卡。
可使用SDIO接口类型的卡
本实验中使用的Micro SD卡属于SDSC(标准容量,最大两G)卡。介绍卡的种类是因为SD协议中的命令也支持这三种类型的卡,因此对STM32中的SDIO接口进行初始化后,上电后就要对接入的卡进行检测、分类,这个过程是通过向卡发送一系列不同的命令,根据卡不同的响应来进行分类。
下面进入代码展开具体讲解。
1.4 代码分析
首先要添加用的库文件,在工程文件夹下Fwlib下我们需添加以下库文件:
FWlib/stm32f10x_gpio.c
FWlib/stm32f10x_rcc.c
FWlib/stm32f10x_usart.c
FWlib/stm32f10x_sdio.c
FWlib/stm32f10x_dma.c
FWlib/misc.c
还要在&stm32f10x_conf.h中把相应的头文件添加进来:
#include&&stm32f10x_dma.h&
#include&&stm32f10x_gpio.h&
#include&&stm32f10x_rcc.h&
#include&&stm32f10x_sdio.h&
#include&&stm32f10x_usart.h&
#include&&misc.h&
保持良好的习惯,从main函数开始分析:
int&main(void)
/*进入到main函数前,启动文件startup(startup_stm32f10x_xx.s)已经调用了在
system_stm32f10x.c中的SystemInit(),配置好了系统时钟,在外部晶振8M的条件下,
设置HCLK&=&72M&&*/
/*&Interrupt&Config&*/
NVIC_Configuration();
/*&USART1&config&*/
USART1_Config();
/*------------------------------&SD&Init&----------------------------------&*/
Status&=&SD_Init();
printf(&&\r\n&这是一个MicroSD卡实验(没有跑文件系统).........\r\n&&&);
if(Status&==&SD_OK)&//检测初始化是否成功
printf(&&&\r\n&SD_Init&初始化成功&\r\n&&&);
printf(&\r\n&SD_Init&初始化失败&\r\n&&);
printf(&\r\n&返回的Status的值为:&%d&\r\n&,Status&);
printf(&&&\r\n&CardType&is&:%d&&,&SDCardInfo.CardType&);
printf(&&&\r\n&CardCapacity&is&:%d&&,&SDCardInfo.CardCapacity&);
printf(&&&\r\n&CardBlockSize&is&:%d&&,&SDCardInfo.CardBlockSize&);
printf(&&&\r\n&RCA&is&:%d&&,&SDCardInfo.RCA);
printf(&&&\r\n&ManufacturerID&is&:%d&\r\n&,&SDCardInfo.SD_cid.ManufacturerID&);
SD_EraseTest();&&&&//擦除测试
SD_SingleBlockTest();&&//单块读写测试
SD_MultiBlockTest();&&//多块读写测试
main函数的流程简单明了:
1、用NVIC_Configuration()初始化好SDIO的中断;
2、用USART1_Config()配置好用于返回调试信息的串口,SD_Init()开始进行SDIO的初始化;
3、最后分别用SD_EraseTest()、SD_SingleBlockTest()、SD_MultiBlockTest()进行擦除,单数据块读写,多数据块读写测试。
下面我们先进入SDIO驱动函数的大头——SD_Init()进行分析:
*&函数名:SD_Init
*&描述&&:初始化SD卡,使卡处于就绪状态(准备传输数据)
*&输入&&:无
*&输出&&:-SD_Error&SD卡错误代码
*&&&&&&&&&成功时则为&SD_OK
*&调用&&:外部调用
SD_Error&SD_Init(void)
/*重置SD_Error状态*/
SD_Error&errorstatus&=&SD_OK;
/*&SDIO&外设底层引脚初始化&*/
GPIO_Configuration();
/*对SDIO的所有寄存器进行复位*/
SDIO_DeInit();
/*上电并进行卡识别流程,确认卡的操作电压&&*/
errorstatus&=&SD_PowerON();
/*如果上电,识别不成功,返回“响应超时”错误&*/
if&(errorstatus&!=&SD_OK)
/*!&&CMD&Response&TimeOut&(wait&for&CMDSENT&flag)&*/
return(errorstatus);
/*卡识别成功,进行卡初始化&&&&*/
errorstatus&=&SD_InitializeCards();
if&(errorstatus&!=&SD_OK)&&&//失败返回
/*!&&CMD&Response&TimeOut&(wait&for&CMDSENT&flag)&*/
return(errorstatus);
/*!&&Configure&the&SDIO&peripheral
上电识别,卡初始化都完成后,进入数据传输模式,提高读写速度
速度若超过24M要进入bypass模式
!&&on&STM32F2xx&devices,&SDIOCLK&is&fixed&to&48MHz
!&&SDIOCLK&=&HCLK,&SDIO_CK&=&HCLK/(2&+&SDIO_TRANSFER_CLK_DIV)&*/
SDIO_InitStructure.SDIO_ClockDiv&=&SDIO_TRANSFER_CLK_DIV;
SDIO_InitStructure.SDIO_ClockEdge&=&SDIO_ClockEdge_R&&&&&&&&&//上升沿采集数据
SDIO_InitStructure.SDIO_ClockBypass&=&SDIO_ClockBypass_D&&//时钟频率若超过24M,要开启此模式
SDIO_InitStructure.SDIO_ClockPowerSave&=&SDIO_ClockPowerSave_D&&&&//若开启此功能,在总线空闲时关闭sd_clk时钟
SDIO_InitStructure.SDIO_BusWide&=&SDIO_BusWide_1b;&&&&&&&&&&&&&&&&&&&&&&&&//1位模式
SDIO_InitStructure.SDIO_HardwareFlowControl&=&SDIO_HardwareFlowControl_D&//硬件流,若开启,在FIFO不能进行发送和接收数据时,数据传输暂停
SDIO_Init(&SDIO_InitStructure);
if&(errorstatus&==&SD_OK)
/*-----------------&Read&CSD/CID&MSD&registers&------------------*/
errorstatus&=&SD_GetCardInfo(&SDCardInfo);&&&//用来读取csd/cid寄存器
if&(errorstatus&==&SD_OK)
/*-----------------&Select&Card&--------------------------------*/
errorstatus&=&SD_SelectDeselect((uint32_t)&(SDCardInfo.RCA&&&&16));&&&//通过cmd7&&,rca选择要操作的卡
if&(errorstatus&==&SD_OK)
errorstatus&=&SD_EnableWideBusOperation(SDIO_BusWide_4b);&&&//开启4bits模式
return(errorstatus);
先从整体上了解这个SD_Init()函数:
1.用&GPIO_Configuration()进行SDIO的端口底层配置
2.分别调用了SD_PowerON()和SD_InitializeCards()函数,这两个函数共同实现了上面提到的卡检测、识别流程。
3.调用SDIO_Init(&SDIO_InitStructure)库函数配置SDIO的时钟,数据线宽度,硬件流(在读写数据的时候,开启硬件流是和很必要的,可以减少出错)
4. 调用SD_GetCardInfo(&SDCardInfo)获取sd卡的CSD寄存器中的内容,在main函数里输出到串口的数据就是这个时候从卡读取得到的。
5. 调用SD_SelectDeselect()选定后面即将要操作的卡。
6.调用SD_EnableWideBusOperation(SDIO_BusWide_4b)开启4bit数据线模式
如果SD_Init()函数能够执行完整个流程,并且返回值是SD_OK的话则说明初始化成功,就可以开始进行擦除、读写的操作了。
下面进入SD_PowerON()函数,分析完这个函数大家就能了解SDIO如何接收、发送命令了。
*&函数名:SD_PowerON
*&描述&&:确保SD卡的工作电压和配置控制时钟
*&输入&&:无
*&输出&&:-SD_Error&SD卡错误代码
*&&&&&&&&&成功时则为&SD_OK
*&调用&&:在&SD_Init()&调用
SD_Error&SD_PowerON(void)
SD_Error&errorstatus&=&SD_OK;
uint32_t&response&=&0,&count&=&0,&validvoltage&=&0;
uint32_t&SDType&=&SD_STD_CAPACITY;
/*!&&Power&ON&Sequence&-----------------------------------------------------*/
/*!&&Configure&the&SDIO&peripheral&*/
/*!&&SDIOCLK&=&HCLK,&SDIO_CK&=&HCLK/(2&+&SDIO_INIT_CLK_DIV)&*/
/*!&&on&STM32F2xx&devices,&SDIOCLK&is&fixed&to&48MHz&*/
/*!&&SDIO_CK&for&initialization&should&not&exceed&400&KHz&*/
/*初始化时的时钟不能大于400KHz*/
SDIO_InitStructure.SDIO_ClockDiv&=&SDIO_INIT_CLK_DIV;&/*&HCLK&=&72MHz,&SDIOCLK&=&72MHz,&SDIO_CK&=&HCLK/(178&+&2)&=&400&KHz&*/
SDIO_InitStructure.SDIO_ClockEdge&=&SDIO_ClockEdge_R
SDIO_InitStructure.SDIO_ClockBypass&=&SDIO_ClockBypass_D&&//不使用bypass模式,直接用HCLK进行分频得到SDIO_CK
SDIO_InitStructure.SDIO_ClockPowerSave&=&SDIO_ClockPowerSave_D&//&空闲时不关闭时钟电源
SDIO_InitStructure.SDIO_BusWide&=&SDIO_BusWide_1b;&&&&&&&&&&&&&&&&&&&&//1位数据线
SDIO_InitStructure.SDIO_HardwareFlowControl&=&SDIO_HardwareFlowControl_D//硬件流
SDIO_Init(&SDIO_InitStructure);
/*!&&Set&Power&State&to&ON&*/
SDIO_SetPowerState(SDIO_PowerState_ON);
/*!&&Enable&SDIO&Clock&*/
SDIO_ClockCmd(ENABLE);
/*下面发送一系列命令,开始卡识别流程*/
/*!&&CMD0:&GO_IDLE_STATE&---------------------------------------------------*/
/*!&&No&CMD&response&required&*/
SDIO_CmdInitStructure.SDIO_Argument&=&0x0;
SDIO_CmdInitStructure.SDIO_CmdIndex&=&SD_CMD_GO_IDLE_STATE;&//cmd0
SDIO_CmdInitStructure.SDIO_Response&=&SDIO_Response_No;&&//无响应
SDIO_CmdInitStructure.SDIO_Wait&=&SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM&=&SDIO_CPSM_E&&//则CPSM在开始发送命令之前等待数据传输结束。
SDIO_SendCommand(&SDIO_CmdInitStructure);&&&&&&&&&//写命令进命令寄存器
errorstatus&=&CmdError();//检测是否正确接收到cmd0
if&(errorstatus&!=&SD_OK)&//命令发送出错,返回
/*!&&CMD&Response&TimeOut&(wait&for&CMDSENT&flag)&*/
return(errorstatus);
/*!&&CMD8:&SEND_IF_COND&----------------------------------------------------*/
/*!&&Send&CMD8&to&verify&SD&card&interface&operating&condition&*/
/*!&&Argument:&-&[31:12]:&Reserved&(shall&be&set&to&'0')
-&[11:8]:&Supply&Voltage&(VHS)&0x1&(Range:&2.7-3.6&V)
-&[7:0]:&Check&Pattern&(recommended&0xAA)&*/
/*!&&CMD&Response:&R7&*/
SDIO_CmdInitStructure.SDIO_Argument&=&SD_CHECK_PATTERN;&&&//接收到命令sd会返回这个参数
SDIO_CmdInitStructure.SDIO_CmdIndex&=&SDIO_SEND_IF_COND;&&//cmd8
SDIO_CmdInitStructure.SDIO_Response&=&SDIO_Response_S&&&&&//r7
SDIO_CmdInitStructure.SDIO_Wait&=&SDIO_Wait_No;&&&&&&&&&&&&//关闭等待中断
SDIO_CmdInitStructure.SDIO_CPSM&=&SDIO_CPSM_E
SDIO_SendCommand(&SDIO_CmdInitStructure);
/*检查是否接收到命令*/
errorstatus&=&CmdResp7Error();
if&(errorstatus&==&SD_OK)&&&&&//有响应则card遵循sd协议2.0版本
CardType&=&SDIO_STD_CAPACITY_SD_CARD_V2_0;&/*!&&SD&Card&2.0&,先把它定义会sdsc类型的卡*/
SDType&=&SD_HIGH_CAPACITY;&&//这个变量用作acmd41的参数,用来询问是sdsc卡还是sdhc卡
else&&//无响应,说明是1.x的或mmc的卡
/*!&&CMD55&*/
SDIO_CmdInitStructure.SDIO_Argument&=&0x00;
SDIO_CmdInitStructure.SDIO_CmdIndex&=&SD_CMD_APP_CMD;
SDIO_CmdInitStructure.SDIO_Response&=&SDIO_Response_S
SDIO_CmdInitStructure.SDIO_Wait&=&SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM&=&SDIO_CPSM_E
SDIO_SendCommand(&SDIO_CmdInitStructure);
errorstatus&=&CmdResp1Error(SD_CMD_APP_CMD);
/*!&&CMD55&*/&&&&&//为什么在else里和else外面都要发送CMD55?
//发送cmd55,用于检测是sd卡还是mmc卡,或是不支持的卡
SDIO_CmdInitStructure.SDIO_Argument&=&0x00;
SDIO_CmdInitStructure.SDIO_CmdIndex&=&SD_CMD_APP_CMD;
SDIO_CmdInitStructure.SDIO_Response&=&SDIO_Response_S&//r1
SDIO_CmdInitStructure.SDIO_Wait&=&SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM&=&SDIO_CPSM_E
SDIO_SendCommand(&SDIO_CmdInitStructure);
errorstatus&=&CmdResp1Error(SD_CMD_APP_CMD);&&//是否响应,没响应的是mmc或不支持的卡
/*!&&If&errorstatus&is&Command&TimeOut,&it&is&a&MMC&card&*/
/*!&&If&errorstatus&is&SD_OK&it&is&a&SD&card:&SD&card&2.0&(voltage&range&mismatch)
or&SD&card&1.x&*/
if&(errorstatus&==&SD_OK)&//响应了cmd55,是sd卡,可能为1.x,可能为2.0
/*下面开始循环地发送sdio支持的电压范围,循环一定次数*/
/*!&&SD&CARD&*/
/*!&&Send&ACMD41&SD_APP_OP_COND&with&Argument&0x&*/
while&((!validvoltage)&&&&(count&&&SD_MAX_VOLT_TRIAL))
//因为下面要用到ACMD41,是ACMD命令,在发送ACMD命令前都要先向卡发送CMD55
/*!&&SEND&CMD55&APP_CMD&with&RCA&as&0&*/
SDIO_CmdInitStructure.SDIO_Argument&=&0x00;
SDIO_CmdInitStructure.SDIO_CmdIndex&=&SD_CMD_APP_CMD;&&&//CMD55
SDIO_CmdInitStructure.SDIO_Response&=&SDIO_Response_S
SDIO_CmdInitStructure.SDIO_Wait&=&SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM&=&SDIO_CPSM_E
SDIO_SendCommand(&SDIO_CmdInitStructure);
errorstatus&=&CmdResp1Error(SD_CMD_APP_CMD);&//检测响应
if&(errorstatus&!=&SD_OK)
return(errorstatus);//没响应CMD55,返回
//acmd41,命令参数由支持的电压范围及HCS位组成,HCS位置一来区分卡是SDSc还是sdhc
SDIO_CmdInitStructure.SDIO_Argument&=&SD_VOLTAGE_WINDOW_SD&|&SDT&&&&//参数为主机可供电压范围及hcs位
SDIO_CmdInitStructure.SDIO_CmdIndex&=&SD_CMD_SD_APP_OP_COND;
SDIO_CmdInitStructure.SDIO_Response&=&SDIO_Response_S&&//r3
SDIO_CmdInitStructure.SDIO_Wait&=&SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM&=&SDIO_CPSM_E
SDIO_SendCommand(&SDIO_CmdInitStructure);
errorstatus&=&CmdResp3Error();&&&&//检测是否正确接收到数据
if&(errorstatus&!=&SD_OK)
return(errorstatus);&&//没正确接收到acmd41,出错,返回
/*若卡需求电压在SDIO的供电电压范围内,会自动上电并标志pwr_up位*/
response&=&SDIO_GetResponse(SDIO_RESP1);&&&//读取卡寄存器,卡状态
validvoltage&=&(((response&&&&31)&==&1)&?&1&:&0);&//读取卡的ocr寄存器的pwr_up位,看是否已工作在正常电压
count++;&&&&&&&&&&&&//计算循环次数
if&(count&&=&SD_MAX_VOLT_TRIAL)&//循环检测超过一定次数还没上电
errorstatus&=&SD_INVALID_VOLTRANGE;&&&&&&//SDIO不支持card的供电电压
return(errorstatus);
/*检查卡返回信息中的HCS位*/
if&(response&&=&SD_HIGH_CAPACITY)&&//判断ocr中的ccs位&,如果是sdsc卡则不执行下面的语句
CardType&=&SDIO_HIGH_CAPACITY_SD_CARD;&&//把卡类型从初始化的sdsc型改为sdhc型
}/*!&&else&MMC&Card&*/
return(errorstatus);
这个函数的流程就是卡的上电、识别操作,如下图:
卡的上电,识别流程:
截图来自《Simplified_Physical_Layer_Spec.pdf》 page27
代码中所有的判断语句都是根据这个图的各个识别走向展开的,最终把卡分为1.0版的SD存储卡,2.0版的SDSC卡和2.0版的SDHC卡。
在这个代码流程中有两点要注意一下:
1.初始化的时钟。SDIO_CK的时钟分为两个阶段,在初始化阶段SDIO_CK的频率要小于400KHz,初始化完成后可把SDIO_CK调整成高速模式,高速模式时超过24M要开启bypass模式,对于SD存储卡即使开启bypass,最高频率不能超过25MHz。
2.CMD8命令。
CMD8命令格式。
CMD8命令中的VHS是用来确认主机SDIO是否支持卡的工作电压的。Check pattern部分可以是任何数值,若SDIO支持卡的工作电压,卡会把接收到的check pattern数值原样返回给主机。
CMD8命令的响应格式R7:
在驱动程序中调用了CmdResp7Error()来检验卡接收命令后的响应。
3.ACMD41命令。
这个命令也是用来进一步检查SDIO是否支持卡的工作电压的,协议要它在调用它之前必须先调用CMD8,另外还可以通过它命令参数中的HCS位来区分卡是SDHC卡还是SDSC卡。
确认工作电压时循环地发送ACMD41,发送后检查在SD卡上的OCR寄存器中的pwr_up位,若pwr_up位置为1,表明SDIO支持卡的工作电压,卡开始正常工作。
同时把ACMD41中的命令参数HCS位置1,卡正常工作的时候检测OCR寄存器中的CCS位,若CCS位为1则说明该卡为SDHC卡,为零则为SDSC卡。
因为ACMD41命令属于ACMD命令,在发送ACMD命令前都要先发送CMD55.
ACMD41命令格式
ACMD41命令的响应(R3),返回的是OCR寄存器的值
OCR寄存器的内容
SD卡上电确认成功后,进入SD_InitializeCards()函数:
*&函数名:SD_InitializeCards
*&描述&&:初始化所有的卡或者单个卡进入就绪状态
*&输入&&:无
*&输出&&:-SD_Error&SD卡错误代码
*&&&&&&&&&成功时则为&SD_OK
*&调用&&:在&SD_Init()&调用,在调用power_on()上电卡识别完毕后,调用此函数进行卡初始化
SD_Error&SD_InitializeCards(void)
SD_Error&errorstatus&=&SD_OK;
uint16_t&rca&=&0x01;
if&(SDIO_GetPowerState()&==&SDIO_PowerState_OFF)
errorstatus&=&SD_REQUEST_NOT_APPLICABLE;
return(errorstatus);
if&(SDIO_SECURE_DIGITAL_IO_CARD&!=&CardType)//判断卡的类型
/*!&&Send&CMD2&ALL_SEND_CID&*/
SDIO_CmdInitStructure.SDIO_Argument&=&0x0;
SDIO_CmdInitStructure.SDIO_CmdIndex&=&SD_CMD_ALL_SEND_CID;
SDIO_CmdInitStructure.SDIO_Response&=&SDIO_Response_L
SDIO_CmdInitStructure.SDIO_Wait&=&SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM&=&SDIO_CPSM_E
SDIO_SendCommand(&SDIO_CmdInitStructure);
errorstatus&=&CmdResp2Error();
if&(SD_OK&!=&errorstatus)
return(errorstatus);
CID_Tab[0]&=&SDIO_GetResponse(SDIO_RESP1);
CID_Tab[1]&=&SDIO_GetResponse(SDIO_RESP2);
CID_Tab[2]&=&SDIO_GetResponse(SDIO_RESP3);
CID_Tab[3]&=&SDIO_GetResponse(SDIO_RESP4);
/*下面开始SD卡初始化流程*/
if&((SDIO_STD_CAPACITY_SD_CARD_V1_1&==&CardType)&||&&(SDIO_STD_CAPACITY_SD_CARD_V2_0&==&CardType)&||&&(SDIO_SECURE_DIGITAL_IO_COMBO_CARD&==&CardType)
||&&(SDIO_HIGH_CAPACITY_SD_CARD&==&CardType))&&//使用的是2.0的卡
/*!&&Send&CMD3&SET_REL_ADDR&with&argument&0&*/
/*!&&SD&Card&publishes&its&RCA.&*/
SDIO_CmdInitStructure.SDIO_Argument&=&0x00;
SDIO_CmdInitStructure.SDIO_CmdIndex&=&SD_CMD_SET_REL_ADDR;&&//cmd3
SDIO_CmdInitStructure.SDIO_Response&=&SDIO_Response_S&//r6
SDIO_CmdInitStructure.SDIO_Wait&=&SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM&=&SDIO_CPSM_E
SDIO_SendCommand(&SDIO_CmdInitStructure);
errorstatus&=&CmdResp6Error(SD_CMD_SET_REL_ADDR,&&rca);&//把接收到的卡相对地址存起来。
if&(SD_OK&!=&errorstatus)
return(errorstatus);
if&(SDIO_SECURE_DIGITAL_IO_CARD&!=&CardType)
/*!&&Send&CMD9&SEND_CSD&with&argument&as&card's&RCA&*/
SDIO_CmdInitStructure.SDIO_Argument&=&(uint32_t)(rca&&&&16);
SDIO_CmdInitStructure.SDIO_CmdIndex&=&SD_CMD_SEND_CSD;
SDIO_CmdInitStructure.SDIO_Response&=&SDIO_Response_L
SDIO_CmdInitStructure.SDIO_Wait&=&SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM&=&SDIO_CPSM_E
SDIO_SendCommand(&SDIO_CmdInitStructure);
errorstatus&=&CmdResp2Error();
if&(SD_OK&!=&errorstatus)
return(errorstatus);
CSD_Tab[0]&=&SDIO_GetResponse(SDIO_RESP1);
CSD_Tab[1]&=&SDIO_GetResponse(SDIO_RESP2);
CSD_Tab[2]&=&SDIO_GetResponse(SDIO_RESP3);
CSD_Tab[3]&=&SDIO_GetResponse(SDIO_RESP4);
errorstatus&=&SD_OK;&/*!&&All&cards&get&intialized&*/
return(errorstatus);
这个函数向卡发送了CMD2和CMD3命令
CMD2命令是要求卡返回它的CID寄存器的内容。
命令的响应格式(R2)。
因为命令格式是136位的,属于长响应。软件接收的信息有128位。在长响应的时候通过SDIO_GetResponse(SDIO_RESP4);中的不同参数来获取CID中的不同数据段的数据。
CMD3命令是要求卡向主机发送卡的相对地址。在接有多个卡的时候,主机要求接口上的卡重新发一个相对地址,这个地址跟卡的实际ID不一样。比如接口上接了5个卡,这5个卡的相对地址就分别为1,2,3,4,5.以后主机SDIO对这几个卡寻址就直接使用相对地址。这个地址的作用就是为了寻址更加简单。
接下来我们回到SD_Init()函数。分析到这里大家应该对SDIO的命令发送和响应比较清楚了。在SD_InitializeCards()之后的SD_GetCardInfo(&SDCardInfo)、 SD_SelectDeselect()和
SD_EnableWideBusOperation(SDIO_BusWide_4b)的具体实现就不再详细分析了,实际就是发送相应的命令,对卡进行相应的操作。
接下来分析main函数中的SD_MultiBlockTest()多块数据读写函数,让大家了解SDIO是怎样传输数据的。
*&函数名:SD_MultiBlockTest
*&描述&&:&&&&多数据块读写测试
*&输入&&:无
*&输出&&:无
void&SD_MultiBlockTest(void)
/*---------------&Multiple&Block&Read/Write&---------------------*/
/*&Fill&the&buffer&to&send&*/
Fill_Buffer(Buffer_MultiBlock_Tx,&MULTI_BUFFER_SIZE,&0x0);
if&(Status&==&SD_OK)
/*&Write&multiple&block&of&many&bytes&on&address&0&*/
Status&=&SD_WriteMultiBlocks(Buffer_MultiBlock_Tx,&0x00,&BLOCK_SIZE,&NUMBER_OF_BLOCKS);
/*&Check&if&the&Transfer&is&finished&*/
Status&=&SD_WaitWriteOperation();
while(SD_GetStatus()&!=&SD_TRANSFER_OK);
if&(Status&==&SD_OK)
/*&Read&block&of&many&bytes&from&address&0&*/
Status&=&SD_ReadMultiBlocks(Buffer_MultiBlock_Rx,&0x00,&BLOCK_SIZE,&NUMBER_OF_BLOCKS);
/*&Check&if&the&Transfer&is&finished&*/
Status&=&SD_WaitReadOperation();
while(SD_GetStatus()&!=&SD_TRANSFER_OK);
/*&Check&the&correctness&of&written&data&*/
if&(Status&==&SD_OK)
TransferStatus2&=&Buffercmp(Buffer_MultiBlock_Tx,&Buffer_MultiBlock_Rx,&MULTI_BUFFER_SIZE);
if(TransferStatus2&==&PASSED)
printf(&\r\n&多块读写测试成功!&&&);
printf(&\r\n&多块读写测试失败!&&&);
把这个函数拿出来分析最重要的一点就是让大家注意在调用了SD_WriteMultiBlocks()这一类读写操作的函数后,一定要调用SD_WaitWriteOperation()[在读数据时调用SD_WaitReadOperation]和SD_GetStatus()来确保数据传输已经结束再进行其它操作。其中的SD_WaitWriteOperation()是用来等待DMA把缓冲的数据传输到SDIO的FIFO的;而SD_GetStatus()是用来等待卡与SDIO之间传输数据完毕的。
最后进入SD_WriteMultiBlocks()函数分析:
*&函数名:SD_WriteMultiBlocks
*&描述&&:从输入的起始地址开始,向卡写入多个数据块,
只能在DMA模式下使用这个函数
注意:调用这个函数后一定要调用
SD_WaitWriteOperation()来等待DMA传输结束
和&&&SD_GetStatus()&检测卡与SDIO的FIFO间是否已经完成传输
*&输入&&:
*&@param&&WriteAddr:&Address&from&where&data&are&to&be&read.
*&@param&&writebuff:&pointer&to&the&buffer&that&contain&the&data&to&be&transferred.
*&@param&&BlockSize:&the&SD&card&Data&block&size.&The&Block&size&should&be&512.
*&@param&&NumberOfBlocks:&number&of&blocks&to&be&written.
*&输出&&:SD错误类型
SD_Error&SD_WriteMultiBlocks(uint8_t&*writebuff,&uint32_t&WriteAddr,&uint16_t&BlockSize,&uint32_t&NumberOfBlocks)
SD_Error&errorstatus&=&SD_OK;
__IO&uint32_t&count&=&0;
TransferError&=&SD_OK;
TransferEnd&=&0;
StopCondition&=&1;
SDIO-&DCTRL&=&0x0;
if&(CardType&==&SDIO_HIGH_CAPACITY_SD_CARD)
BlockSize&=&512;
WriteAddr&/=&512;
/*******************add,没有这一段容易卡死在DMA检测中*************************************/
/*!&&Set&Block&Size&for&Card,cmd16,若是sdsc卡,可以用来设置块大小,若是sdhc卡,块大小为512字节,不受cmd16影响&*/
SDIO_CmdInitStructure.SDIO_Argument&=&(uint32_t)&BlockS
SDIO_CmdInitStructure.SDIO_CmdIndex&=&SD_CMD_SET_BLOCKLEN;
SDIO_CmdInitStructure.SDIO_Response&=&SDIO_Response_S&&&//r1
SDIO_CmdInitStructure.SDIO_Wait&=&SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM&=&SDIO_CPSM_E
SDIO_SendCommand(&SDIO_CmdInitStructure);
errorstatus&=&CmdResp1Error(SD_CMD_SET_BLOCKLEN);
if&(SD_OK&!=&errorstatus)
return(errorstatus);
/*********************************************************************************/
/*!&&To&improve&performance&&*/
SDIO_CmdInitStructure.SDIO_Argument&=&(uint32_t)&(RCA&&&&16);
SDIO_CmdInitStructure.SDIO_CmdIndex&=&SD_CMD_APP_CMD;&//&cmd55
SDIO_CmdInitStructure.SDIO_Response&=&SDIO_Response_S
SDIO_CmdInitStructure.SDIO_Wait&=&SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM&=&SDIO_CPSM_E
SDIO_SendCommand(&SDIO_CmdInitStructure);
errorstatus&=&CmdResp1Error(SD_CMD_APP_CMD);
if&(errorstatus&!=&SD_OK)
return(errorstatus);
/*!&&To&improve&performance&*///&&pre-erased,在多块写入时可发送此命令进行预擦除
SDIO_CmdInitStructure.SDIO_Argument&=&(uint32_t)NumberOfB&&//参数为将要写入的块数目
SDIO_CmdInitStructure.SDIO_CmdIndex&=&SD_CMD_SET_BLOCK_COUNT;&&//cmd23
SDIO_CmdInitStructure.SDIO_Response&=&SDIO_Response_S
SDIO_CmdInitStructure.SDIO_Wait&=&SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM&=&SDIO_CPSM_E
SDIO_SendCommand(&SDIO_CmdInitStructure);
errorstatus&=&CmdResp1Error(SD_CMD_SET_BLOCK_COUNT);
if&(errorstatus&!=&SD_OK)
return(errorstatus);
/*!&&Send&CMD25&WRITE_MULT_BLOCK&with&argument&data&address&*/
SDIO_CmdInitStructure.SDIO_Argument&=&(uint32_t)WriteA
SDIO_CmdInitStructure.SDIO_CmdIndex&=&SD_CMD_WRITE_MULT_BLOCK;
SDIO_CmdInitStructure.SDIO_Response&=&SDIO_Response_S
SDIO_CmdInitStructure.SDIO_Wait&=&SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM&=&SDIO_CPSM_E
SDIO_SendCommand(&SDIO_CmdInitStructure);
errorstatus&=&CmdResp1Error(SD_CMD_WRITE_MULT_BLOCK);
if&(SD_OK&!=&errorstatus)
return(errorstatus);
SDIO_DataInitStructure.SDIO_DataTimeOut&=&SD_DATATIMEOUT;
SDIO_DataInitStructure.SDIO_DataLength&=&NumberOfBlocks&*&BlockS
SDIO_DataInitStructure.SDIO_DataBlockSize&=&(uint32_t)&9&&&&4;
SDIO_DataInitStructure.SDIO_TransferDir&=&SDIO_TransferDir_ToC
SDIO_DataInitStructure.SDIO_TransferMode&=&SDIO_TransferMode_B
SDIO_DataInitStructure.SDIO_DPSM&=&SDIO_DPSM_E
SDIO_DataConfig(&SDIO_DataInitStructure);
SDIO_ITConfig(SDIO_IT_DATAEND,&ENABLE);
SDIO_DMACmd(ENABLE);
SD_DMA_TxConfig((uint32_t&*)writebuff,&(NumberOfBlocks&*&BlockSize));
return(errorstatus);
写操作在发送正式的多块写入命令CMD25前调用了CMD23进行预写,这样有利于提高写入的速度。在代码的最后调用了SDIO_ITConfig(),SDIO的数据传输结束中断就是这个时候开启的,数据传输结束时,就进入到stm32f10x_it.c文件中的中断服务函数SDIO_IRQHandler()中处理了,中断服务函数主要就是负责清中断。
最后讲一下官方原版的驱动中的一个bug。
在官方原版的SDIO驱动的SD_ReadBlock()、SD_ReadMultiBlocks()、SD_WriteBlock()和SD_WriteMultiBlocks()这几个函数中,发送读写命令前,漏掉了发送一个CMD16命令,这个命令用于设置读写SD卡的块大小。缺少这个命令很容易导致程序运行时卡死在循环检测DMA传输结束的代码中,网上很多人直接移植ST官方例程时,用3.5版库函数和这个4.5版的SDIO驱动移植失败,就是缺少了这段用CMD16设置块大小的代码。
到这里,终于讲解完毕啦!这个讲解如果能让你从对SDIO一无所知到大概了解的话,我的目标就达到啦,想要更深入了解还是要好好地配合这个例程中我在代码中的注释和附带资料SD2.0协议《Simplified_Physical_Layer_Spec.pdf》好好研究一番! ^_^
注意:这个例程是没有跑文件系统的,而是直接就去读卡的block,这样的话就会破坏卡的分区,在实验完成之后,你再把卡插到电脑上时,电脑会提示你要重新初始化卡,这是正常想象,并不是本实验把你的卡弄坏了,如果卡原来有资料的请先把数据备份了再进行测试。但跑文件系统时就不会出现这种问题,有关文件系统的操作将在下一讲的教程中讲解。
1.5实验现象
将野火STM32开发板供电(DC5V),插上JLINK,插上串口线(两头都是母的交叉线),插上MicroSD卡( 我用的是1G ,经测试,本驱动也适用于2G以上的卡(sdhc卡)),打开超级终端,配置超级终端为-N-1,将编译好的程序下载到开发板,即可看到超级终端打印出如下信息:
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:35683次
排名:千里之外
原创:46篇
转载:91篇
(5)(2)(4)(1)(3)(3)(24)(9)(21)(58)(1)(3)(3)

我要回帖

更多关于 vivox9外屏碎了保修吗 的文章

 

随机推荐