您的位置:首页 > 其它

SD卡初始化及读写流程 【转】

2012-11-28 14:28 288 查看
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卡有所谓操作模式(operation mode)的概念,每种操作模式又具体对应一种或多种状态,主机通过发送命令可以使SD卡在不同的状态间转换,SD卡则接受命令,并根据自己现在所处状态做出不同的响应。



系统上电时刻或者搜寻SD卡时,SD卡控制器应该处于SD卡识别模式;SD卡在刚接入系统时刻也处于这种模式,并且处于此模式下的Idle状态。

SD卡识别模式:在这种模式下,控制器会检验SD卡的工作电压范围,识别SD卡类型,并要求它们发送各自的相对地址(Relative Card Address);这些操作在SD卡各自的CMD线上进行。所有的操作均使用默认的 SD卡识别时钟频率(identification clock rate)

SD卡复位:发送GO_IDLE_STATE(CMD0)到SD卡后,除处于非活动状态(Inactive state)之外的SD卡都会进入空闲状态(Idle state);在Idle状态,SD卡的CMD线处于输入模式,默认相对地址为0x0000,默认驱动寄存器设定为最低速度,最大驱动电流能力。

工作条件检测:

在控制器和SD卡进行任何通信之前,控制器不清楚SD卡支持的工作电压范围,故而控制器首先使用默认的电压发送一条reset指令(CMD0),紧跟着的CMD8指令,用于取得SD卡支持工作电压范围数据。SD卡通过检测CMD8的参数部分来检查控制器使用的工作电压,控制器通过分析回传的CMD8参数部分来校验SD卡是否可以在所给电压下工作。如果SD卡可以在指定电压下工作,则它回送CMD8的命令响应字,其中包含check voltage, check pattern。如果SD卡不支持所给电压,则SD卡不会给出任何响应信息,并继续处于Idle状态。在PLV2.0(physical
layer version2.0)下,在首次执行ACMD41之前,必须执行CMD8指令,用以初始化SDHC卡,SDHC卡根据是否接收到CMD8指令来鉴别控制器是否支持PLV2.0协议。使用低电压的控制器也必须在ACMD41命令之前发送CMD8,避免可以工作在两种电压模式下的SD卡因为没有接收到CMD8, 而默认工作在高电压环境下,被误认为是只支持高电压工作模式。

SD_SEND_OP_COND(ACMD41)命令的目的是给予SD卡控制器一个识别SD卡是否可以在所给Vdd范围下工作的机制,如果SD卡无法在指定Vdd范围内工作,则它会进入非活动状态(Inactive state)。要注意的是,ACMD41是应用相关型命令,因而,每次发出的ACMD41命令都必须紧跟在一条APP_CMD(CMD55)命令之后。在空闲态(Idle State)下使用的CMD55命令使用默认的卡相对地址(RCA)0x0000。

每次控制器发送CMD0复位SD卡后,都要重新进行系列初始化操作(CMD8,ACMD41...)。

如果ACMD41指令的OCR比特位为0,控制器可以查询各个SD卡,并决定它们共同的工作电压范围。在作为查询的ACMD41指令发送之后,SD卡并不会开始初始化过程,直到控制器重新发送一条ACMD41指令。



SD卡初始化和识别过程:

SD卡的初始化开始于接收到ACMD41指令之后,ACMD指令的HCS(Host Capacity Support)位如果设定为1的话,表明控制器支持SDHC卡,否则表示不支持。

在CMD8命令发送之后的ACMD41指令其功能有所扩展,在参数里多了HCS部分,在响应里面多了CCS(Card Capacity Status)部分。HCS参数会被不响应CMD8命令的SD卡所抛弃。控制器向不响应CMD8的卡发送ACMD41指令时,HCS位应该设置为零0。如果向SDHC卡发送HCS位为0的ACMD41命令,SDHC卡返回的响应,其busy标识位永远为0,代表忙状态。HCS标识位用来表明SD卡是否已经完成初始化,如果未完成,HCS为零,否则为1,如果HCS为0,控制器会重复发送ACMD41指令,SD卡只检查首次接收到的ACMD41指令的HCS位。

响应CMD8的SD卡发送的对于ACMD41指令响应会包含CCS部分,控制器只检查HCS标志位为1的响应所包含的CCS位。CCS=1表明其为SDHC卡,否则为标准SD卡。

控制器随后发送ALL_SEND_CID(CMD2)命令,查询各个卡的CID(unique card identification)值,还没有被识别的SD卡(处于Ready状态)会发送CID值作为响应,发送完CID值之后,SD卡进入识别状态(Identification state),然后控制器发送CMD3(SEND_RELATIVE_ADDR)命令,要求各个SD卡发送一个新的相对地址(RCA),RCA在之后的数据传输模式中用于寻址。RCA发送完之后。SD卡进入Stand-by状态,在这个状态,如果控制器想要给SD卡分配一个新的RCA,它可以发送另一条CMD3命令给SD卡。最后发布的RCA为SD卡的真实RCA。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: