SD卡驱动相关内容

SD卡驱动相关内容 

http://blog.csdn.net/josh915/archive/2010/08/24/5835707.aspx

一)

先对 SD 卡有一个感性认识:

SD 卡的技术是基于 MultiMedia 卡( MMC )格式上发展而来,大小和 MMC 差不多,尺寸为 32mm x 24mm x 2.1mm SD 卡与 MMC 卡保持着向上兼容。

内部结构: SD 卡内部主要分两部分:存储介质( nandflash )和主控制器。主控制器多位以 51 为核心而设计的专用处理器,内部 PLL 可以倍频到近 100m ,带内部 DMA ,最主要的是 SD 控制器和 NAND 控制器。而作为存储介质的 nandflash 1Gbit 128Gbit

分类:

MMC 卡:结构类似 SD 卡,采用 MMC 协议。

SD1.0 SD1.0 卡最大支持 2Gbyte

SD2.0: SD2.0 卡最大容量 HCSD 可达 32Gbyte 。从 MMC SD1.0 再到 SD2.0 协议是向上兼容的。也就是说 SD2.0 可以兼容 SD1.0 协议, SD1.0 可以兼容 MMC 卡协议。即 MMC 协议的指令可以操作 SD1.0,Sd2.0 ,同理 SD1.0 协议的命令可以操作 sd2.0 卡。这就是我们平时看到初始化 SD 卡的时候只需要 CMD0 CMD1 两条命令就可以让上面上类卡进入传输状态的原因: MMC 卡协议初始化只定义了 CMD0 CMD1

SD 卡接口: SD 卡接口支持 SPI 模式和 SD 模式。 SD 模式下采用 4 线并行模式,作为多媒体存储设备为提高传输速度都会采用这种接口。而 SPI 更方便低端 MCU 访问传输速度有限。

硬件引脚封装:如图所示:

     SD卡驱动相关内容_第1张图片

 

 

共九个脚,定义如下:

SD卡驱动相关内容_第2张图片

 

 

我们的板子上用跳线选择了 SD 模式和 SPI 模式的连线,用 SPI 将中间四根线用跳线连接即可。注意我们板子的 SPI 用的是 SPI2 来操作 SD 卡的。

有了感性的认识后,我们来了解一下 SD 卡协议命令的格式, MMC 卡只有基本命令,即 CMD0-CMD38 ,当然这中间不是连续,请大家看协议的命令表吧, SD 卡有基本命令和特定命令,特定命令必须跟在基本命令 CMD55 后面,即要想用特定命令,必须先发一条 CMD55 通知 SD 卡,然后才能发送特定的命令。每条命令由 6BYTE 组成,分三部分, 1 字节为操作码, 2-5 字节为参数,有的命令没有参数,那就填 0 ,有参数的根据参数说明而定,最后一字节为 CRC 校验,不过 SPI 模式不需要 CRC 校验,故可以任意填写,不过有几个特殊命令有指定的 CRC 校验码,必须加上。每条命令都有响应,根据命令的不同可能有 R1 R1B R2 R3 OCR )寄存器响应,通过它们判断命令是否操作成功。

对命令有了解后,只要知道各个操作的过程就可以操作 SD 卡了,主要操作有初始化,读、写、擦除等,下面分别介绍:

1

初始化步骤:

1     

延时至少 74clock ,等待 SD 卡内部操作完成,在 MMC 协议中有明确说明。

2 CS 低电平选中 SD 卡。

3 )发送 CMD0 ,需要返回 0x01 ,进入 Idle 状态

4 )为了区别 SD 卡是 2.0 还是 1.0 ,或是 MMC 卡,这里根据协议向上兼容的原理,首先发送只有 SD2.0 才有的命令 CMD8 ,如果 CMD8 返回无错误,则初步判断为 2.0 卡,进一步发送命令循环发送 CMD55+ACMD41 ,直到返回 0x00 ,确定 SD2.0 卡初始化成功,进入 Ready 状态,再发送 CMD58 命令来判断是 HCSD 还是 SCSD ,到此 SD2.0 卡初始化成功。如果 CMD8 返回错误则进一步判断为 1.0 卡还是 MMC 卡,循环发送 CMD55+ACMD41 ,返回无错误,则为 SD1.0 卡,到此 SD1.0 卡初始成功,如果在一定的循环次数下,返回为错误,则进一步发送 CMD1 进行初始化,如果返回无错误,则确定为 MMC 卡,如果在一定的次数下,返回为错误,则不能识别该卡,初始结束。

5 CS 拉高。

2

读步骤:

1     

发送 CMD17 (单块)或 CMD18 (多块)读命令,返回 0x00

2     

接收数据开始令牌 0xfe (或 0xfc + 正式数据 512Bytes + CRC 校验 2Bytes

默认正式传输的数据长度是 512Bytes ,可用 CMD16 设置块长度。

3

写步骤:

1     

发送 CMD24 (单块)或 CMD25 (多块)写命令,返回 0x00

2     

发送数据开始令牌 0xfe (或 0xfc + 正式数据 512Bytes + CRC 校验 2Bytes

4

擦除步骤:

1     

发送 CMD32 ,跟一个参数来指定首个要擦除的起始地址( SD 手册上说是块号)

2     

发送 CMD33, ,指定最后的地址

3     

发送 CMD38 ,擦除指定区间的内容

3 步顺序不能颠倒。

最后说一下我的一点体会: SD 卡就是一个存储器,只不过用命令的方式来进行操作,我们只要掌握了各条命令及操作方式,就可以灵活的操作 SD 卡了,另外我所了解的 IC 卡也是类似的原理,还有就是建议开始看 MMC 的协议,简单明了易懂些,有了对 MMC 卡的一些了解后看 SD 卡协议就容易多

 

 

本文来自 CSDN 博客,转载请标明出处: http://blog.csdn.net/cuitianxiang/archive/2010/04/19/5503173.aspx

 

 

 

二) SD 卡调试关键点:

 

1.      上电时要延时足够长的时间给 SD 卡一个准备过程,在我的程序里是 5 秒,根据不同的卡设置不同的延时时间。 SD 卡初始化第一步在发送 CMD 命令之前,在片选有效的情况下首先要发送至少 74

时钟,否则将有可能出现 SD 卡不能初始化的问题。

 

2.      SD 卡发送复位命令 CMD0 后,要发送版本查询命令 CMD8 ,返回状态一般分两种,若返回 0x01 表示此 SD 卡接受 CMD8, 也就是说此 SD 卡支持版本 2 ;若返回 0x05 则表示此 SD 卡支持版本 1 。因为不同版本的 SD 卡操作要求有不一样的地方,所以务必查询 SD 卡的版本号,否则也会出现 SD 卡无

法正常工作的问题。

 

3.      理论上要求发送 CMD58 获得 SD 卡电压参数,但实际过程中由于事先都知道了 SD 卡的工作

电压,因此可省略这一步简化程序。协议书上也建议尽量不要用这个命令。

 

4.      SD 卡读写超时时间要按照协议说明书书上的给定值 ( 读超时: 100ms ;写超时: 250ms) ,这个值要在程序中准确计算出来,否则将会出现不能正常读写数据的问题。我自己定义了一个计算公式:超

时时间 =(8/clk)*arg

 

5.      2GB 以内的 SD ( 标准卡 ) 2GB 以上的 SD ( 大容量卡 ) 在地址访问形式上不同,这一点尤其要注意,否则将会出现无法读写数据的问题。如标准卡在读写操作时,对读或写命令令牌当中的地址域符初值 0x10 ,表示对第 16 个字节以后的地址单元进行操作 ( 前提是此 SD 卡支持偏移读写操作 ) ,而对大容量卡读或写命令令牌当中的地址域符初值 0x10 时,则表示对第 16 块进行读写操作,而且大容量卡只支持

块读写操作,块大小固定为 512 字节,对其进行字节操作将会出错。

 

6.      对某一块要进行写操作时最好先执行擦出命令,这样写入的速度就能大大提高。进行擦除操作时不管是标准卡还是大容量卡都按块操作执行,也就是一次擦除至少 512 字节。

 

7.      对标准卡进行字节操作时,起始和终止必须在一个物理扇区内,否则将不能进行读写操作。实际操作过程中建议用块操作以提高效率。不管是标准卡还是大容量卡一个读写命令只能对一个块进行操

作,不允许跨物理层地址操作。

 

8.      在写数据块前要先写入若干个 dummy data 字节,写完一个块数据时,主机要监测 MISO 数据线,如果从机处于忙状态这根数据线会保持低电平,这样主机就可以根据这根数据线的状态以决定是否发送下一个命令,在从机没有释放 MISO 数据线之前,主机绝对不能执行其他命令,否则将会导致写入的数

据出错,而且从机也不会响应主机的命令。

 

9.      SPI 模式下, CRC 校验是被忽略的,但依然要求主从机发送 CRC 码,只是数值可以是任意

值,一般主机的 CRC 码通常设为 0x00 0xFF

 

读多块操作和写多块操作的传输停止形式不一样,读多块操作时用用命令 CMD12 终止传输,而写多

块操作时用 Stop Tran Token( 停止传输令牌,值为 0xFD) 终止传输。

----------------------------------------------------------------------------------------

1
初始化步骤:

1 )延时至少 74clock ,等待 SD 卡内部操作完成,在 MMC 协议中有明确说明。

2 CS 低电平选中 SD 卡。
3 )发送 CMD0 ,需要返回 0x01 ,进入 Idle 状态
4 )为了区别 SD 卡是 2.0 还是 1.0 ,或是 MMC 卡,这里根据协议向上兼容的原理,首先发送只有 SD2.0 才有的命令 CMD8 ,如果 CMD8 返回无错误,则初步判断为 2.0 卡,进一步发送命令循环发送 CMD55+ACMD41 ,直到返回 0x00 ,确定 SD2.0 卡初始化成功,进入 Ready 状态,再发送 CMD58 命令来判断是 HCSD 还是 SCSD ,到此 SD2.0 卡初始化成功。如果 CMD8 返回错误则进一步判断为 1.0 卡还是 MMC 卡,循环发送 CMD55+ACMD41 ,返回无错误,则为 SD1.0 卡,到此 SD1.0 卡初始成功,如果在一定的循环次数下,返回为错误,则进一步发送 CMD1 进行初始化,如果返回无错误,则确定为 MMC 卡,如果在一定的次数下,返回为错误,则不能识别该卡,初始结束。

5 CS 拉高。
2
、读步骤:
1     发送 CMD17 (单块)或 CMD18 (多块)读命令,返回 0x00
2     接收数据开始令牌 0xfe (或 0xfc + 正式数据 512Bytes + CRC 校验 2Bytes
  默认正式传输的数据长度是 512Bytes ,可用 CMD16 设置块长度。
3
、写步骤:
1     发送 CMD24 (单块)或 CMD25 (多块)写命令,返回 0x00
2     发送数据开始令牌 0xfe (或 0xfc + 正式数据 512Bytes + CRC 校验 2Bytes
4
、擦除步骤:
1     发送 CMD32 ,跟一个参数来指定首个要擦除的起始地址( SD 手册上说是块号)
2     发送 CMD33, ,指定最后的地址
3     发送 CMD38 ,擦除指定区间的内容
3 步顺序不能颠倒。
最后说一下我的一点体会: SD 卡就是一个存储器,只不过用命令的方式来进行操作,我们只要掌握了各条命令及操作方式,就可以灵活的操作 SD 卡了,另外我所了解的 IC 卡也是类似的原理,还有就是建议开始看 MMC 的协议,简单明了易懂些,有了对 MMC 卡的一些了解后看 SD 卡协议就容易多了。
下面是我的程序,仅供参考

你可能感兴趣的:(SD卡驱动相关内容)