驱动文件使用的13年的ST的官方SD卡驱动,且经过安富莱硬汉的实验,最初实现热插拔,基本没有问题(没有做特别大量的测试)。但是同时加上他的代码后,我的内存卡热插拔基本无法使用,经排查,发现SD卡在SD_PowerON)阶段中的,发送CMD8: SEND_IF_COND后的响应异常,会卡在电压检测那里,直到超时,电压一直为0,然后换了个别的卡,就没有那种现象。可以基本断定是卡之间的差异。
后来,又经过屏蔽同事的代码,查找的只要屏蔽他在100us的定时中断中,can的发送,现象就没了。至今没有查找到为什么。
为了解决这个问题,在SD_PowerON中做了些改动,当CMD8响应不正常的时候,让他重新尝试从CMD0到CMD8的命令的发送,尝试3遍。发现当响应不正常的时候,重新尝试1遍,就可解决这种现象。
这个图是那个Banq的出问题体的SD卡
这个是闪迪的SD卡。
出问题的那个卡,retyn=1,说明重试了一次,闪迪的不用重试。
下面简单复制下SD的上电识别过程的一些基本知识。
STM32 控制器目前最高支持《Physical Layer SimplifiedSpecification V2.0》定义的 SD卡,STM32控制器对 SD卡进行数据读写之前需要识别卡的种类:V1.0标准卡、V2.0标准卡、V2.0 高容量卡或者不被识别卡。
SD 卡系统包括主机和 SD卡)定义了两种操作模式:卡识别模式和数据传输模式。在系统复位后,主机处于卡识别模式,寻找总线上可用的 SDIO 设备;同时,SD卡也处于卡识别模式,直到被主机识别到,即当 SD卡接收到 SEND_RCACMD3)命令后,SD卡就会进入数据传输模式,而主机在总线上所有卡被识别后也进入数据传输模式。在每个操作模式下,SD卡都有几种状态,参考表 37-4,通过命令控制实现卡状态的切换。
1 卡识别模式
在卡识别模式下,主机会复位所有处于“卡识别模式”的 SD卡,确认其工作电压范围,识别 SD卡类型,并且获取 SD卡的相对地址卡相对地址较短,便于寻址)。在卡识别过程中,要求 SD卡工作在识别时钟频率 FOD 的状态下。卡识别模式下 SD卡状态转换如
主机上电后,所有卡处于空闲状态,包括当前处于无效状态的卡。主机也可以发送GO_IDLE_STATECMD0)让所有卡软复位从而进入空闲状态,但当前处于无效状态的卡并不会复位。
主机在开始与卡通信前,需要先确定双方在互相支持的电压范围内。SD卡有一个电压支持范围,主机当前电压必须在该范围可能才能与卡正常通信。SEND_IF_CONDCMD8)命令就是用于验证卡接口操作条件的主要是电压支持)。卡会根据命令的参数来检测操作条件匹配性,如果卡支持主机电压就产生响应,否则不响应。而主机则根据响应内容确定卡的电压匹配性。CMD8是 SD卡标准 V2.0 版本才有的新命令,所以如果主机有接收到响应,可以判断卡为 V2.0 或更高版本 SD卡(上边提的到问题,就出在此处,没有响应)。
SD_SEND_OP_CONDACMD41)命令可以识别或拒绝不匹配它的电压范围的卡。ACMD41命令的 VDD 电压参数用于设置主机支持电压范围,卡响应会返回卡支持的电压范围。对于对 CMD8有响应的卡,把 ACMD41 命令的 HCS 位设置为 1,可以测试卡的容量类型,如果卡响应的 CCS 位为 1 说明为高容量 SD 卡,否则为标准卡。卡在响应ACMD41之后进入准备状态,不响应 ACMD41 的卡为不可用卡,进入无效状态。ACMD41是应用特定命令,发送该命令之前必须先发 CMD55。
ALL_SEND_CIDCMD2)用来控制所有卡返回它们的卡识别号CID),处于准备状态的卡在发送 CID 之后就进入识别状态。之后主机就发送 SEND_RELATIVE_ADDRCMD3)命令,让卡自己推荐一个相对地址RCA)并响应命令。这个 RCA是 16bit地址,而 CID 是128bit地址,使用 RCA 简化通信。卡在接收到 CMD3 并发出响应后就进入数据传输模式,并处于待机状态,主机在获取所有卡 RCA之后也进入数据传输模式。
懒惰不会让你一下子跌到
但会在不知不觉中减少你的收获;
勤奋也不会让你一夜成功
但会在不知不觉中积累你的成果
越努力,越幸运。