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

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卡识别模式;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卡初始化和识别过程:

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。
SD卡初始化及读写流程 【转】 - 丁丁 - 每一天,一个新的开始

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值