当前位置:首页 > 单片机 > 单片机
[导读]SD卡已经看了两天了,主要是因为测试出来的卡容量不对,所以一直找原因,最终还是发现了,总比不过是单位上面出现了问题,或许是之前没有接触到SD的缘故吧,所以对其中的一些寄存器很不了解,一切都是重新开始,对照

SD卡已经看了两天了,主要是因为测试出来的卡容量不对,所以一直找原因,最终还是发现了,总比不过是单位上面出现了问题,或许是之前没有接触到SD的缘故吧,所以对其中的一些寄存器很不了解,一切都是重新开始,对照这寄存器手册,理解程序,修改程序。一步步还是总结一下!

首先关于SD卡的协议是有必要了解的,我今天花了一上午的课堂时间来理解这个SD卡的协议,就是基于这个文档的,这个文档很适合入门SD协议的(个人认为)。http://download.csdn.net/detail/king_bingge/5218183

初识SD之后,就可以开始正式学习SD卡了!

一、要使用SD卡,那么首先肯定得对SD卡进行初始化,那么如何进行初始化呢?(命令的参数暂且不提)

1、这里涉及到很多指令了。协议规定了在给SD卡上电之后需要给出至少74个时钟脉冲后,才能进行相关的SD初始化工作,虽然是这么说,但是我不给74个时钟,他照样能初始化,看看。


for(i=0;i<10;i++)SD_SPI_ReadWriteByte(0XF);


但是,或许为了能够更加成功的初始化吧,所以有这个规定所以,我们还是规规矩矩的好,给它74个时钟,没关系的嘛!


2、然后就是协议中说到当我们复位或者上电的时候,SD卡的SD控制寄存器处于卡识别模式中的空闲模式的,暂且这样称吧。本来我们是不需要发送复位命令了的,但是我们不知道我们的SD所支持的电压范围。所以,我们最好还是先给出一条复位指令,然后紧接着一条获取工作电压的指令,这样也是比较保险,如果多SD卡工作电压有疑问的,那么就得去看芯片手册了。有了这个知识,那下面的代码就不成问题了


retry=20;

do

{

r1=SD_SendCmd(CMD0,0,0x95);//进入IDLE状态

}while((r1!=0X01)&&retry--);

SD_Type=0;//默认无卡

if(r1==0X01)

{

if(SD_SendCmd(CMD8,0x1AA,0x87)==1)//SDV2.0

{

for(i=0;i<4;i++)buf[i]=SD_SPI_ReadWriteByte(0XFF);//GettrailingreturnvalueofR7resp

if(buf[2]==0X01&&buf[3]==0XAA)//卡是否支持2.7~3.6V

3、协议上还提到ACMD41命令的目的是给予 SD卡控制器一个识别 SD卡是否可以在所给Vdd 范围下工作的机制,如果 SD 卡无法在指定 Vdd 范围内工作,则它会进入非活动状态(Inactive state ),所以我们接下来需要发送这个命令,但是在发送这个命令之前,要知道这是一个应用型的命令,所以要加上CMD55命令,所以有了下面的代码。



if(buf[2]==0X01&&buf[3]==0XAA)//卡是否支持2.7~3.6V

{

retry=0XFFFE;

do

{

SD_SendCmd(CMD55,0,0X01);//发送CMD55

r1=SD_SendCmd(CMD41,0x40000000,0X01);//发送CMD41

}while(r1&&retry--);

if(retry&&SD_SendCmd(CMD58,0,0X01)==0)//鉴别SD2.0卡版本开始//获取供电状态

{

for(i=0;i<4;i++)buf[i]=SD_SPI_ReadWriteByte(0XFF);//得到OCR值

if(buf[0]&0x40)SD_Type=SD_TYPE_V2HC;//检查CCS

elseSD_Type=SD_TYPE_V2;

}


这样就获取了卡的类型了,至此卡的初始化基本完成,当然根据协议上,我们还可以在这里修改相对地址之类的。如果有必要的话,可以这样做!


二、初始化完SD卡,接下来如果你想查看我们SD的容量,可以这样做!

之前就是因为卡容量的问题,所以郁闷了好久,理解了个大概!注意这里函数名是读取扇区数,实际上返回的值是我们卡的容量,这里得注意了。

1、首先看代码


u32SD_GetSectorCount(void)

{

u8csd[16];

u32Capacity_KB,Capacity_MB;

u8n;

u16csize;

//取CSD信息,如果期间出错,返回0

if(SD_GetCSD(csd)!=0)return0;

n=(csd[5]&15)+((csd[10]&128)>>7)+((csd[9]&3)<<1)+2;

csize=(csd[8]>>6)+((u16)csd[7]<<2)+((u16)(csd[6]&3)<<10)+1;

Capacity_KB=(u32)csize<<(n-10);//得到扇区数,这里的单位是KB

Capacity_MB=Capacity_KB/1024;

returnCapacity_MB;

}


这个计算的问题必须得看SD卡的手册,也就是128位的CSD寄存器。这里我把我分析的过程贴出来,我不得不说比较乱,或许只有我自己能看懂了,懒得整理了,仅供参考!


MySD_Card

CSD寄存器中的值如下:

007fff32bit(127-96)csd0-csd3

5f5983cbbit(95--64)csd4-csd701011111010110011000001111001011

76dbdfffbit(63--32)csd8-csd1101110110110110111101111111111111

96400097bit(31---0)csd12-csd15

csize{62,73}

csize_muti{47,49}

read{80,83}

csize=111100101101=3885

csize_muti=111=7

read=1001=9

计算公式:

blocknr=(csize+1)*mult=

mult=(csize_muti<8)*(2^(csize_muti+2))

block_len=(read<12)*(2^(read))

capacity=blocknr*block_len=13*4*3516*98304

依据下面代码来计算我的容量:

n=(csd[5]&15)+((csd[10]&128)>>7)+((csd[9]&3)<<1)+2;

csize=(csd[8]>>6)+((u16)csd[7]<<2)+((u16)(csd[6]&3)<<10)+1;

Capacity_KB=(u32)csize<<(n-10);//得到扇区数,这里的单位是KB//007fff325f5983cb76dbdfff96400097

Capacity_MB=Capacity_KB/1024;

1、(csd[8]>>6)得到的是bit62和bit63的值去掉2位

2、((u16)csd[7] << 2)得到的是bit64--bit69的值 去掉6位

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭