凌阳科技大学计划论坛 竞赛及毕设版块电子竞赛专区[分享]SD卡驱动程序——不断更新 07/12/23更新!!!!

1  /  4  页    1  2  3  4  跳转
发表新主题 回复该主题

标题: [分享]SD卡驱动程序——不断更新 07/12/23更新!!!!

本主题由 版主 longer2514 于 2009-5-26 9:29:52 执行 主题置顶/取消 操作

大一

 
  • UID:65544
  • 来自:
  • 精华:0
  • 积分:107
  • 帖子:54
  • 注册: 2006-12-15
  • 状态: 离线
  • 威望:106.00
  • 金钱:432.30 元

[分享]SD卡驱动程序——不断更新 07/12/23更新!!!!

大家只要下载我上传的文件就可以了。



 附件: 您所在的用户组无法下载或查看附件
在直接下载不好用的情况下大家试一下迅雷或者其他的下载软件


大家可以把文件SD_Driver.c和SD.asm放在自己的程序里使用,其中函数PutPortraitChar是控制我使用的LCD的语句,大家可以修改删掉。如果还有问题,我愿意为大家解答
我的MCU不具备SPI接口,SPI接口是通过软件模拟出来的。

再给大家一些附加的信息,希望有所帮助:
本文关键词:SD SPI CMD0 CMD55 ACMD41 初始化

首先,我要感谢leajian大侠,在他的关于SD卡的帖子里学到了很多知识,没有他的帮助是不可能完成这个初始化程序的,leajian,谢谢你!
这些天没有出门,一直在家研究SD卡的SPI模式的初始化顺序,这里为大家总结了一下编写该程序所需要的知识:

            1.SD卡的官方资料(我承认这个资料很垃圾,比起民间的技术总结它的内容可谓又臭又长,但是作为基础也要了解一下,SD协议不用看)
            2.清晰明了的MMC卡时序图(虽然这个是MMC卡的,但是在初始化的时候CMD0的时序是一样的,可以借鉴)

再来说一说鸡毛蒜皮的细节:
1.为了使SD卡初始化进入SPI模式,我们需要使用的命令有3个:CMD0,ACMD41,CMD55(使用ACMD类的指令前应先发CMD55,CMD55起到一个切换到ACMD类命令的作用)。

2.为什么在使用CMD0以后不使用CMD1?CMD1是MMC卡使用的指令,虽然本文并不想讨论MMC卡的问题,但是我还是要说:为了实现兼容性,上电或者发送CMD0后,应该首先发送CMD55+ACMD41确认是否有回应,如果有回应则为SD卡,如果等回应超时,则可能是MMC卡,再发CMD1确认。

3.正确的回应内容应该是:
            CMD0——0x01(SD卡处于in-idle-state)
            CMD55——0x01(SD卡处于in-idle-state)
            ACMD41——0x00(SD卡跳出in-idle-state,完成初始化准备接受下一条指令)

            这里要说的是如果最后的回应内容还是0x01的话,可以循环发送CMD55+ACMD41,直到回应的内容0x00。

4.在所有的指令中,唯独CMD0特殊,在向SD卡发送以前需要向SD卡发送74+个时钟。那么为什么要74个CLK呢?因为在上电初期,电压的上升过程据SD卡组织的计算约合64个CLK周期才能到达SD卡的正常工作电压他们管这个叫做Supply ramp up time,其后的10个CLK是为了与SD卡同步,之后开始CMD0的操作,严格按照此项操作,一定没有问题。

5.关于SD卡的SPI总线,在读入数据时SD卡的SPI是CLK的上升沿输入锁存,输出数据也是在上升沿。

6.向SD卡写入一个CMD或者ACMD指令的过程是这样的:
首先使CS为低电平,SD卡使能;其次在SD卡的Din写入指令;写入指令后还要附加8个填充时钟,是SD卡完成内部操作;之后在SD卡的Dout上接受回应;回应接受完毕使CS为低电平,再附加8个填充时钟。

7.在SD卡的Din没有数据写入时,应使Din保持高电平。

附件附件:

 附件: 您所在的用户组无法下载或查看附件

solomonexp 最后编辑于 2007-12-23 22:56:26
引用 回复
 

大一

 
  • UID:68497
  • 来自:
  • 精华:0
  • 积分:101
  • 帖子:49
  • 注册: 2007-03-19
  • 状态: 离线
  • 威望:104.00
  • 金钱:210.40 元

很棒的程序

感謝....

引用 回复
 

大一

 
  • UID:68497
  • 来自:
  • 精华:0
  • 积分:101
  • 帖子:49
  • 注册: 2007-03-19
  • 状态: 离线
  • 威望:104.00
  • 金钱:210.40 元

請問CMD16可以設定為1嗎??(default是512)


引用 回复
 

大一

 
  • UID:68497
  • 来自:
  • 精华:0
  • 积分:101
  • 帖子:49
  • 注册: 2007-03-19
  • 状态: 离线
  • 威望:104.00
  • 金钱:210.40 元

請問CMD16可以設定為1嗎??(default是512)

引用 回复
 

大一

 
  • UID:65544
  • 来自:
  • 精华:0
  • 积分:107
  • 帖子:54
  • 注册: 2006-12-15
  • 状态: 离线
  • 威望:106.00
  • 金钱:432.30 元

以下是引用iamqq在2007-8-7 14:56:00的发言:

請問CMD16可以設定為1嗎??(default是512)

对于读操作来说1-512都可以,但是对于写操作来说唯一有效的是512。


引用 回复
 

大一

 
  • UID:68497
  • 来自:
  • 精华:0
  • 积分:101
  • 帖子:49
  • 注册: 2007-03-19
  • 状态: 离线
  • 威望:104.00
  • 金钱:210.40 元

所以說

當READ時 可以讀取任一個ADDRESS的DATA囉??

[em09]
引用 回复
 

大一

 
  • UID:65544
  • 来自:
  • 精华:0
  • 积分:107
  • 帖子:54
  • 注册: 2006-12-15
  • 状态: 离线
  • 威望:106.00
  • 金钱:432.30 元

以下是引用iamqq在2007-8-9 9:42:00的发言:

所以說

當READ時 可以讀取任一個ADDRESS的DATA囉??

[em09]

好像不是这样的吧,这个我也在试,但是我记得SD卡中的地址好像应该是每512作为一个地址的。你是不是想随意读取任意一个Byte啊?

引用 回复
 

大一

 
  • UID:68497
  • 来自:
  • 精华:0
  • 积分:101
  • 帖子:49
  • 注册: 2007-03-19
  • 状态: 离线
  • 威望:104.00
  • 金钱:210.40 元

我是想隨意讀取任意一個BYTE

可行嗎??

引用 回复
 

大一

 
  • UID:65544
  • 来自:
  • 精华:0
  • 积分:107
  • 帖子:54
  • 注册: 2006-12-15
  • 状态: 离线
  • 威望:106.00
  • 金钱:432.30 元

以下是引用iamqq在2007-8-9 13:12:00的发言:

我是想隨意讀取任意一個BYTE

可行嗎??

嗯,可能不太可行,不知道你想存的是什么样的数据,如果只是零星的Byte而不是数据流一样的Byte,那么就不是很适合,在读写时需要不断调整读写的大小。


引用 回复
 

大一

 
  • UID:68497
  • 来自:
  • 精华:0
  • 积分:101
  • 帖子:49
  • 注册: 2007-03-19
  • 状态: 离线
  • 威望:104.00
  • 金钱:210.40 元

會有這樣的想法

是因為記憶體可能不夠用

所以才會想每次讀取一個BYTE

還有你說"在读写时需要不断调整读写的大小"

但讀取的長度不是設定一次就可以了嗎

為何要不斷調整??

[em06]
引用 回复
 

大一

 
  • UID:65544
  • 来自:
  • 精华:0
  • 积分:107
  • 帖子:54
  • 注册: 2006-12-15
  • 状态: 离线
  • 威望:106.00
  • 金钱:432.30 元

以下是引用iamqq在2007-8-10 9:30:00的发言:

會有這樣的想法

是因為記憶體可能不夠用

所以才會想每次讀取一個BYTE

還有你說"在读写时需要不断调整读写的大小"

但讀取的長度不是設定一次就可以了嗎

為何要不斷調整??

[em06]

CMD16的功能呢个是:Selects a block length (in bytes) for all following block commands (read & write).

对于读写的要求是:The only valid block length for write is 512 bytes. The valid block length for read is 1 to 512 bytes. A set block length of less than 512 bytes will cause a write error. The card has a default block length of 512 bytes. CMD16 is not mandatory if the default is accepted.

所以由于你要设定一个低于512 的数值进行读操作,当下一次写操作之前必须设回512,以后再进行读操作时要再设成低于512的数值,如此循环往复,我说的是这个意思[em07]


引用 回复
 

大一

 
  • UID:68497
  • 来自:
  • 精华:0
  • 积分:101
  • 帖子:49
  • 注册: 2007-03-19
  • 状态: 离线
  • 威望:104.00
  • 金钱:210.40 元

感謝大大...

所以說對MUC而言

還是要有512BYTES的BUFFER來對SD CARD做R/W

   

[em08]
引用 回复
 

大一

 
  • UID:65544
  • 来自:
  • 精华:0
  • 积分:107
  • 帖子:54
  • 注册: 2006-12-15
  • 状态: 离线
  • 威望:106.00
  • 金钱:432.30 元

以下是引用iamqq在2007-8-10 13:29:00的发言:

感謝大大...

所以說對MUC而言

還是要有512BYTES的BUFFER來對SD CARD做R/W

   

[em08]

其实就是一个512容量的数组就可以了,大家写程序都是这么做的,方便。当然,61板是16位的,高8位会浪费掉,无所谓啦[em07]
引用 回复
 

超级版主

 
  • UID:30216
  • 来自:水泊
  • 精华:3
  • 积分:10098
  • 帖子:5701
  • 注册: 2005-03-19
  • 状态: 离线
  • 威望:8763.00
  • 金钱:13738.85 元

在read操作时是可以按照byte来做的,没有问题。SD card内并不是没512byte一个地址,而是字节地址!所以,按byte来read是可行的。

但是,就像楼主提到的,当你按照byte来read,但是在write的时候又必须重新设定为512bytes/block,这个重新设置的动作可能会导致SD card工作不稳定。目前测试过,当你设定好block size=1,此后如果不进行重新设定的动作,一般是没有问题的,但是重新设定后会在某些情况下出现不稳定!

引用 回复
 

小学生

 
  • UID:75612
  • 来自:
  • 精华:0
  • 积分:8
  • 帖子:5
  • 注册: 2007-08-09
  • 状态: 离线
  • 威望:5.00
  • 金钱:110.30 元

回复:[分享]SD卡驱动程序——不断更新 07/08/20更新!!!!

我看官方的命令,总是看不懂
能告诉我基本的几个命令的意义吗?
象CMD0,CMD16,CMD17,CMD24
引用 回复
 
1  /  4  页    1  2  3  4  跳转
发表新主题 回复该主题

现在时间是:2010-09-04 04:14:16 京ICP备05061966号