sd卡容量计算的详解及程序实现

说说为什么想起来写这篇文档,主要因为本然当时写程序的时候对这部分挺疑惑的,同时看见好多人在论坛提问类似的问题,所以本人也是菜鸟,就写这篇文档帮助其他人的同时也提升自己的表达能力和总结能力,供同仁们参考参考,好了废话不多说了,首先在本次详细说明之前建议读者自己有一份《sd卡协议(物理层)》说明文档,因为本人一下内容都是通过这个文档说明,如果想详细了解sd卡必须消息阅读本文档,在此贴出本人分享的下载的地址 http://pan.baidu.com/s/1hqn6GXQ       点击打开链接,首先简单介绍一些sd卡的分类,目前市面上大致分为三类根据sd卡的容量,
容量等级
容量范围
磁盘格式
SD
上限至2GB
FAT 12, 16
SDHC
2GB至 32GB
FAT 32
SDXC
32GB至2TB
exFAT

其中sdxc卡是超高速sd卡,目前在为控制开发用的不多,同时由于sdxc协议与SDSC,SDHC协议是不同的,所以这次就只讲SDSC和SDHC卡的容量计算的协议:1.讲SDSC卡的容量计算,根据文档给出的公式如图所示中:


详细可以参考文档P81,现在我们知道了公式,只要知道其中的未知量即可求出SDSC的容量,接下来我看看如何得到图中的一些未知量:C_SIZE,C_SIZE_MULT,READ_BL_LEN三个未知量,因为关于一些sd卡的一些的一些内容的寄存器CSD:The Card-Specific Data register provides information regarding access to the card contents.因为这个是普通的低容量卡所以我们要看V1.0版本的协议,记住特别重要我们看看,这个寄存器CSD中我们需要的一些内容我简单按照协议把我们需要的一些看整理出来,详细看协议V1.0,所以我们知道这些数据,如果单片机可以读取寄存器中的这些数据值根据公式即可计算出来,由于我使用的是SPI读取SD卡,所以数据传输方式是MSB到LSB,所以我们接受方式是从最高到最低接受的需要特别注意这也是很多人看不懂源程序最主要的原因,说怎么和协议公式不对应,先讲 C_SIZE,在上图可以看见bit数是12,同时在寄存器的【73:62】,从寄存器最高的127数到【73:62】,所以 C_SIZE的12位分别在接受字节的CSD[6]、CSD[7]、CSD[8]中,其中占CSD[6]低2位,CSD[7]的8位,CSD[8]的高两位,加在一起正好是12位,同时参照协议可以得到C_SIZE_MULT在CSD[9]的低两位,CSD[10]的高一位,READ_BL_LEN在寄存器的CSD[5]的低4位,所以根据上述的公式可以写程序如下:

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= (u32)csize << (n - 9);//得到扇区数   
其中的n=C_SIZE_MULT+READ_BL_LEN+2;其中公式中的&就是取寄存器中相应的位数,可以参考协议仔细比对一下就会明白的,可能大家会对之后 一句话疑惑

Capacity= (u32)csize << (n - 9);//得到扇区数 ,因为扇区数=容量/块大小(本次是512Byte),Capacity= (u32)csize << n /512;整理公式之后即可等到最后一句话的结果,好了,关于SDSC容量的计算就说到这里:下面说关于SDHC容量的计算,由于SDHC的块大小是固定的512Byte,所以计算公式简单很多,注意的是SDHC容量计算必须看协议V2.0中的CSD寄存器,我们首先还是那样看一下计算公式吧其中化双下滑杠的部分需要特别注意一下,在后面我会提高,由上图的公式可以看到我们只需要一个未知量C_SIZE,这个如果可以知道即可计算SD卡的容量,还是如上面的方法我们看一下C_SIZE在csd寄存器中的位置及寄存器的宽度还是由高127开始接受,按协议可以计算出C_SIZE在接受字节位置是CSD【7】、CSD【8】、CSD【9】,其中占CSD【7】的低6位,CSD【8】的8位,CSD【9】的8为,所以我们在程序中计算如下:

	csize = csd[9] + ((u16)csd[8] << 8) + 1;
		Capacity = (u32)csize << 10;//得到扇区数	
首先看到程序第一问题你可能会有这样的疑惑,CSD【7】怎么没有用上,是不是有问题,其实是没有问题的,你仔细看上图双下划线的话是什么,大致意思是:文件的高六位必须设置为0,这是为什么呢?其实是以为如果按照c_size的位宽最大它的容量可以达到2TB,但是我们也知道SDHC的容量范围是2~32GB,所以高6位必须设置为0,关于止呕后一句话的意思就是扇区数=容量/512.所以我们看公式应该是(C_SIZE+1)*1024*512/512=(C_SIZE+1)*1024= csize << 10,即可得到上述的结果。本人也是菜鸟,仅是凭着本人的理解写出来,如果有什么错误的地方还希望大神们评论指出,在这里感谢原子哥,程序的实现是参考他的。

  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值