当前位置:首页 > 单片机 > 单片机
[导读]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位

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

stm32f103zet6是一种嵌入式-微控制器的集成电路(IC),是由ST公司开发的STM32F1系列的其中一种,芯体尺寸是32位,速度是72MHz,程序存储器容量是256KB,程序存储器类型是FLASH,RAM容量是...

关键字: stm32f103zet6 datasheet 引脚图

有时候,我们需要保存少量数据,但是用外扩的ROM又觉得不方便,这时候自然就想到了芯片内部是否自带flash(闪存),据我了解,stm32内部的应该是nor flash,因为如果是nand flash的话,肯定速度是跟不上...

关键字: Flash nor stm32f103zet6

定时器TIM3产生四路PWM波输出。首先介绍一下PWM吧,算是给自己充电,脉冲宽度调制(PWM),是英文“Pulse Width Modulation ”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制...

关键字: pwm stm32f103zet6 定时器

进行串口配置的步骤一、初始化GPIO,配置GPIO模式一个结构体GPIO_InitTypeDef{GPIOMode_TypeDef GPIO_Mode//GPIO模式,输入,输出?uint16_t GPIO_Pin//哪...

关键字: stm32f103zet6 串口学习

由于前面买的核心板,供电老有问题,使得我现在的项目又改用了以前用的F103ZET6微控制器!1、实验目的1)产生脉宽任意可调的单脉冲(在允许的范围内)2、硬件:通用定时器3、通用定时器43、单脉冲模式介绍单脉冲模式

关键字: stm32f103zet6 通用定时器 单脉冲模式

在完成IO驱动彩屏的试验后,就准备着手使用FSMC来驱动彩屏,先了解一下预备知识一、所谓的FSMC机制简单介绍FSMC在这篇博文里面很清楚,推荐一下http://blog.csdn.net/king_bingge/art...

关键字: fsmc stm32f103zet6 驱动tft

STM32F103ZET6里共有8个定时器,其中高级定时器有TIM1-TIM5、TIM8,共6个。这里需要使用定时器的级联功能,ST的RM0008 REV12的P388和P399页上有说明对于特定的定时器,怎么去选择级联...

关键字: pwm stm32f103zet6 定时器 级联方式

stm32内部集成的ADC介绍一、参考电压的范围为/*2.4V≦ V ≦3.6V所以它的输入模拟电压范围0

关键字: dma stm32f103zet6

代码这里可以下载http://download.csdn.net/detail/king_bingge/5353528一、uc/OS的实时性是靠什么实现的?1、uC/OS的实时性就是靠定时中断来完成。2、每个时钟节拍到来...

关键字: ii os stm32f103zet6 uc 移植os

看门狗,这个东西在哪都能看见,关于其中简单介绍在我的另一篇博文中有的,那是关于arm11的,不过大体一样http://blog.csdn.net/king_bingge/article/details/8510713一、...

关键字: stm32f103zet6 看门狗
关闭
关闭