下载

1下载券

加入VIP
  • 专属下载特权
  • 现金文档折扣购买
  • VIP免费专区
  • 千万文档免费下载

上传资料

关闭

关闭

关闭

封号提示

内容

首页 SD卡详细中文资料

SD卡详细中文资料.pdf

SD卡详细中文资料

从入门到放弃
2011-08-03 0人阅读 举报 0 0 暂无简介

简介:本文档为《SD卡详细中文资料pdf》,可适用于IT/计算机领域

SD卡管脚定义及C语言讲解()SDSDSDSD卡的引脚定义:SD卡引脚功能详述:引脚编号SD模式SPI模式名称类型描述名称类型描述CDDATIO或PP卡检测数据线#CSI片选CMDPP命令回应DII数据输入VSSS电源地VSSS电源地VDDS电源VDDS电源CLKI时钟SCLKI时钟VSSS电源地VSSS电源地DATIO或PP数据线DOO或PP数据输出DATIO或PP数据线RSVDATIO或PP数据线RSV注:S:电源供给I:输入O:采用推拉驱动的输出PP:采用推拉驱动的输入输出SD卡SPI模式下与单片机的连接图:SD卡支持两种总线方式:SD方式与SPI方式。其中SD方式采用线制使用CLK、CMD、DAT~DAT进行数据通信。而SPI方式采用线制使用CS、CLK、DataIn、DataOut进行数据通信。SD方式时的数据传输速度与SPI方式要快采用单片机对SD卡进行读写时一般都采用SPI模式。采用不同的初始化方式可以使SD卡工作于SD方式或SPI方式。这里只对其SPI方式进行介绍。()SPISPISPISPI方式驱动SDSDSDSD卡的方法SD卡的SPI通信接口使其可以通过SPI通道进行数据读写。从应用的角度来看采用SPI接口的好处在于很多单片机内部自带SPI控制器不光给开发上带来方便同时也见降低了开发成本。然而它也有不好的地方如失去了SD卡的性能优势要解决这一问题就要用SD方式因为它提供更大的总线数据带宽。SPI接口的选用是在上电初始时向其写入第一个命令时进行的。以下介绍SD卡的驱动方法只实现简单的扇区读写。)命令与数据传输命令传输SD卡自身有完备的命令系统以实现各项操作。命令格式如下:命令的传输过程采用发送应答机制过程如下:每一个命令都有自己命令应答格式。在SPI模式中定义了三种应答格式如下表所示:字节位含义开始位始终为参数错误地址错误擦除序列错误CRC错误非法命令擦除复位闲置状态字节位含义开始位始终为参数错误地址错误擦除序列错误CRC错误非法命令擦除复位闲置状态溢出CSD覆盖擦除参数写保护非法卡ECC失败卡控制器错误未知错误写保护擦除跳过锁/解锁失败锁卡字节位含义开始位始终为参数错误地址错误擦除序列错误CRC错误非法命令擦除复位闲置状态~全部操作条件寄存器高位在前写命令的例程:向SD卡中写入命令并返回回应的第二个字节unsignedcharWriteCommandSD(unsignedchar*CMD){unsignedchartmpunsignedcharretry=unsignedchari禁止SD卡片选SPICS=发送个时钟信号WriteByteSD(xFF)使能SD卡片选SPICS=向SD卡发送字节命令forforforfor(i=i<xi){WriteByteSD(*CMD)}获得位的回应ReadByteSD()readthefirstbyte,ignoreitdodododo{读取后位tmp=ReadByteSD()retry}whilewhilewhilewhile((tmp==xff)(retry<))returnreturnreturnreturn(tmp)})初始化SD卡的初始化是非常重要的只有进行了正确的初始化才能进行后面的各项操作。在初始化过程中SPI的时钟不能太快否则会造初始化失败。在初始化成功后应尽量提高SPI的速率。在刚开始要先发送至少个时钟信号这是必须的。在很多读者的实验中很多是因为疏忽了这一点而使初始化不成功。随后就是写入两个命令CMD与CMD使SD卡进入SPI模式初始化时序图:初始化例程:初始化SD卡到SPI模式unsignedcharSDInit(){unsignedcharretry,tempunsignedchariunsignedcharCMD={x,x,x,x,x,x}SDPortInit()初始化驱动端口InitFlag=将初始化标志置forforforfor(i=i<xfi){WriteByteSD(xff)发送至少个时钟信号}向SD卡发送CMDretry=dodododo{为了能够成功写入CMD,在这里写次temp=WriteCommandSD(CMD)retryifififif(retry==){超过次returnreturnreturnreturn(INITCMDERROR)CMDError!}}whilewhilewhilewhile(temp!=)回应h停止写入发送CMD到SD卡CMD=xCMDCMD=xFFretry=dodododo{为了能成功写入CMD,写次temp=WriteCommandSD(CMD)retryifififif(retry==){超过次returnreturnreturnreturn(INITCMDERROR)CMDError!}}whilewhilewhilewhile(temp!=)回应h停止写入InitFlag=初始化完毕初始化标志清零SPICS=片选无效returnreturnreturnreturn()初始化成功})读取CIDCID寄存器存储了SD卡的标识码。每一个卡都有唯一的标识码。CID寄存器长度为位。它的寄存器结构如下:名称域数据宽度CID划分生产标识号MID:OEM应用标识OID:产品名称PNM:产品版本PRV:产品序列号PSN:保留-:生产日期MDT:CRC校验合CRC:未使用始终为-:它的读取时序如下:与此时序相对应的程序如下:读取SD卡的CID寄存器字节成功返回unsignedcharReadCIDSD(unsignedchar*Buffer){读取CID寄存器的命令unsignedcharCMD={xA,x,x,x,x,xFF}unsignedchartemptemp=SDReadBlock(CMD,Buffer,)readbytesreturnreturnreturnreturn(temp)})读取CSDCSD(CardSpecificData)寄存器提供了读写SD卡的一些信息。其中的一些单元可以由用户重新编程。具体的CSD结构如下:名称域数据宽度单元类型CSD划分CSD结构CSDSTRUCTURER:保留R:数据读取时间TAACR:数据在CLK周期内读取时间(NSAC*)NSACR:最大数据传输率TRANSPEEDR:卡命令集合CCCR:最大读取数据块长READBLLENR:允许读的部分块READBLPARTIALR:非线写块WRITEBLKMISALIGNR:非线读块READBLKMISALIGNR:DSR条件DSRIMPR:保留R:设备容量CSIZER:最大读取电流VDDminVDDRCURRMINR:最大读取电流VDDmaxVDDRCURRMAXR:最大写电流VDDminVDDWCURRMINR:最大写电流VDDmaxVDDWCURRMAXR:设备容量乘子CSIZEMULTR:擦除单块使能ERASEBLKENR:擦除扇区大小SECTORSIZER:写保护群大小WPGRPSIZER:写保护群使能WPGRPENABLER:保留R:写速度因子RWFACTORR:最大写数据块长度WRITEBLLENR:允许写的部分部WRITEBLPARTIALR:保留R:文件系统群FILEOFRMATGRPRW:拷贝标志COPYRW:永久写保护PERMWRITEPROTECTRW:暂时写保护TMPWRITEPROTECTRW:文件系统FILFORMATRW:保留RW:CRCCRCRW:未用始终为:读取CSD的时序:相应的程序例程如下:读SD卡的CSD寄存器共字节返回说明读取成功unsignedcharReadCSDSD(unsignedchar*Buffer){读取CSD寄存器的命令unsignedcharCMD={x,x,x,x,x,xFF}unsignedchartemptemp=SDReadBlock(CMD,Buffer,)readbytesreturnreturnreturnreturn(temp)})读取SD卡信息综合上面对CID与CSD寄存器的读取可以知道很多关于SD卡的信息以下程序可以获取这些信息。如下:返回SD卡的容量单位为MsectorcountandmultiplierMBareinu==CSIZE(^(CSIZEMULT))SD卡的名称voidvoidvoidvoidSDgetvolumeinfo(){unsignedchariunsignedcharctempVOLUMEINFOTYPESDvolumeInfo,*vinfvinf=SDvolumeInfoInitthepointoer读取CSD寄存器ReadCSDSD(sectorBufferdat)获取总扇区数vinf>sectorcount=sectorBufferdatxvinf>sectorcount<<=vinf>sectorcount=sectorBufferdatvinf>sectorcount<<=vinf>sectorcount=(sectorBufferdatxc)>>获取multipliervinf>sectormultiply=sectorBufferdatxvinf>sectormultiply<<=vinf>sectormultiply=(sectorBufferdatx)>>获取SD卡的容量vinf>sizeMB=vinf>sectorcount>>(vinf>sectormultiply)getthenameofthecardReadCIDSD(sectorBufferdat)vinf>name=sectorBufferdatvinf>name=sectorBufferdatvinf>name=sectorBufferdatvinf>name=sectorBufferdatvinf>name=sectorBufferdatvinf>name=xendflag}以上程序将信息装载到一个结构体中这个结构体的定义如下:typedeftypedeftypedeftypedefstructstructstructstructSDVOLUMEINFO{SDSDCardinfounsignedintsizeMBunsignedcharsectormultiplyunsignedintsectorcountunsignedcharname}VOLUMEINFOTYPE)扇区读扇区读是对SD卡驱动的目的之一。SD卡的每一个扇区中有个字节一次扇区读操作将把某一个扇区内的个字节全部读出。过程很简单先写入命令在得到相应的回应后开始数据读取。扇区读的时序:扇区读的程序例程:unsignedcharSDReadSector(unsignedlongsector,unsignedchar*buffer){unsignedcharretry命令unsignedcharCMD={x,x,x,x,x,xFF}unsignedchartemp地址变换由逻辑块地址转为字节地址sector=sector<<sector=sector*CMD=((sectorxFF)>>)CMD=((sectorxFF)>>)CMD=((sectorxFF)>>)将命令写入SD卡retry=dodododo{为了保证写入命令一共写次temp=WriteCommandMMC(CMD)retryifififif(retry==){returnreturnreturnreturn(READBLOCKERROR)blockwriteError!}}whilewhilewhilewhile(temp!=)ReadStartByteformMMCSDCard(FEhStartByte)Nowdataisready,youcanreaditoutwhilewhilewhilewhile(ReadByteMMC()!=xfe)readPos=SDgetdata(,buffer)字节被读出到buffer中returnreturnreturnreturn}其中SDgetdata函数如下:获取数据到buffer中voidvoidvoidvoidSDgetdata(unsignedintBytes,unsignedchar*buffer){unsignedintjforforforfor(j=j<Bytesj)*buffer=ReadByteSD()})扇区写扇区写是SD卡驱动的另一目的。每次扇区写操作将向SD卡的某个扇区中写入个字节。过程与扇区读相似只是数据的方向相反与写入命令不同而已。扇区写的时序:扇区写的程序例程:写个字节到SD卡的某一个扇区中去返回说明写入成功unsignedcharSDwritesector(unsignedlongaddr,unsignedchar*Buffer){unsignedchartmp,retryunsignedinti命令unsignedcharCMD={x,x,x,x,x,xFF}addr=addr<<addr=addr*CMD=((addrxFF)>>)CMD=((addrxFF)>>)CMD=((addrxFF)>>)写命令到SD卡中去retry=dodododo{为了可靠写入写次tmp=WriteCommandSD(CMD)retryifififif(retry==){returnreturnreturnreturn(tmp)sendcommamdError!}}whilewhilewhilewhile(tmp!=)在写之前先产生个时钟信号forforforfor(i=i<i){ReadByteSD()}写入开始字节WriteByteMMC(xFE)现在可以写入个字节forforforfor(i=i<i){WriteByteMMC(*Buffer)}CRCByteWriteByteMMC(xFF)DummyCRCWriteByteMMC(xFF)CRCCodetmp=ReadByteMMC()readresponseifififif((tmpxF)!=x)写入的个字节是未被接受{SPICS=returnreturnreturnreturn(WRITEBLOCKERROR)Error!}等到SD卡不忙为止因为数据被接受后SD卡在向储存阵列中编程数据whilewhilewhilewhile(ReadByteMMC()!=xff){}禁止SD卡SPICS=returnreturnreturnreturn()写入成功}此上内容在笔者的实验中都已调试通过。单片机采用STCLE单片机(SD卡的初始化电压为V~V操作电压为V~V因此不能用V单片机或进行分压处理)工作于M的时钟下由于所采用的单片机中没硬件SPI采用软件模拟SPI因此读写速率都较慢。如果要半SD卡应用于音频、视频等要求高速场合则需要选用有硬件SPI的控制器或使用SD模式当然这就需要各位读者对SD模式加以研究有了SPI模式的基础SD模式应该不是什么难事。

用户评价(0)

关闭

新课改视野下建构高中语文教学实验成果报告(32KB)

抱歉,积分不足下载失败,请稍后再试!

提示

试读已结束,如需要继续阅读或者下载,敬请购买!

文档小程序码

使用微信“扫一扫”扫码寻找文档

1

打开微信

2

扫描小程序码

3

发布寻找信息

4

等待寻找结果

我知道了
评分:

/15

SD卡详细中文资料

VIP

在线
客服

免费
邮箱

爱问共享资料服务号

扫描关注领取更多福利