在上一章中,我们对SD卡做了介绍,了解了SDIO的通信协议,接下来我们将要介绍SD卡从上电到可正常读写期间,具体是怎么通信的。
1、SD卡操作模式
STM32控制器对SD卡进行数据读写之前需要识别卡的种类:V1.0标准卡、V2.0标准卡、V2.0高容量卡或者不被识别卡。
SD卡系统(包括主机和SD卡)定义了两种操作模式:卡识别模式和数据传输模式。在系统复位后,主机处于卡识别模式,寻找总线上可用的SDIO设备;同时,SD卡也处于卡识别模式,直到被主机识别到,即当SD卡接收到SEND_RCA(CMD3)命令后,SD卡就会进入数据传输模式,而主机在总线上所有卡被识别后也进入数据传输模式。在每个操作模式下,SD卡都有几种状态,通过命令控制实现卡状态的切换,如下表所示:
操作模式 | SD卡状态 |
无效模式(Inactive) | 无效状态(Inactive State) |
卡识别模式(Card identification mode) | 空闲状态(Idle State) |
准备状态(Ready State) | |
识别状态(Identification State) | |
数据传输模式(Data transfer mode) | 待机状态(Stand-by State) |
传输状态(Transfer State) | |
发送数据状态(Sending-data State) | |
接收数据状态(Receive-data State) | |
编程状态(Programming State) | |
断开连接状态(Disconnect State) |
2、卡识别模式
在卡识别模式下,主机会复位所有处于“卡识别模式”的SD卡,确认其工作电压范围,识别SD卡类型,并且获取SD卡的相对地址(卡相对地址较短,便于寻址)。
在卡识别过程中,SD卡工作在识别时钟频率FOD(最大400KHz),且1线传输方式的状态下。
卡识别模式状态切换图如下所示:
根据识别转换图,我们对转换流程进行讲解。
2.1、SD卡Reset
主机上电后,所有卡处于空闲状态,包括当前处于无效状态的卡。主机也可以发送GO_IDLE_STATE(CMD0)让所有卡软复位从而进入空闲状态,但当前处于无效状态的卡并不会复位。
上电或CMD0
后,所有卡的CMD数据线都处于输入模式,等待接收下一条命令。这些卡被初始化为一个默认的SD卡相对地址(RCA=0x0000
),并设置SD卡驱动级寄存器(DSR
)默认为最低的速度和最高的驱动能力。
2.2、SD卡操作条件的确认
在主机和SD卡开始通信时,主机可能不知道SD卡支持的电压,SD卡也可能不知道它是否支持当前提供的电压。主机发出一个复位命令(CMD0
),同时假定它电压可能被SD卡支持。为了验证电压,在《Physical Layer Specification Version 2.00》文档中定义了以下新命令(CMD8
)。
注意:CMD8是SD卡标准V2.0版本才有的新命令,所以如果主机有接收到响应,可以判断卡为V2.0或更高版本SD卡。
SEND_IF_COND
(CMD8
)用于验证SD卡接口操作条件。SD卡通过分析CMD8
的参数来检测操作条件的有效性,主机通过分析CMD8
的响应来检测操作条件的有效性。提供的电压通过命令CMD8
的参数VHS域来指定。SD卡以VHS中指定的电压作为当前提供的电压。通过CRC和Check Pattern(‘10101010b’)来检测主机与SD卡之间通信的有效性。
- 如果SD卡支持在提供的电压上操作,在响应命令的参数中会包含提供的电压和Check Pattern(‘10101010b’)。
- 如果SD卡不支持在提供的电压下工作,它没有任何响应返回并保持在Idle状态。为初始化大容量SD存储卡,必须在第一个
ACMD41
之前发出CMD8
。接收CMD8
能被SD卡识别到,需要主机支持《 Physical Layer Specification Version 2.00》和SD卡支持该新功能。
SD_SEND_OP_COND(ACMD41)命令可以识别或拒绝不匹配它的电压范围的卡。ACMD41命令的VDD电压参数用于设置主机支持电压范围,卡响应会返回卡支持的电压范围。不能在指定范围内进行数据传输的SD卡,应放弃总线操作,进入Inactive 状态。OCR寄存器定义了相关的电压等级。
注意:
ACMD41
是特定应用程序的命令,因此APP_CMD (CMD55)应该始终在ACMD41之前被发送。在idle_state中用于CMD55的RCA将是SD卡的默认值(RCA = 0 x0000)。
通过在命令ACMD41
的参数中将OCR
设置为0,主机可以查询每个卡并确定公共电压范围,然后再将超出范围的卡发送到 Inactive 状态。ACMD41
只是作为查询发出,SD卡不会开始初始化。 之后,主机可以选择一个工作电压,并在这种情况下重新发出ACMD41,将不兼容的卡发送到 Inactive状态。在初始化过程中,主机不允许改变工作电压范围。
2.3、SD卡初始化和识别过程
总线被激活后,主机开始SD卡的初始化和识别过程(参考下图)。初始化过程从SD_SEND_OP_COND
(ACMD41
)开始,通过设置操作条件和OCR
(Operation Conditions Register
)中的HCS
(Host Capacity Support
)位。
HCS(Host Capacity Support)位设置为 :
- 1: 表示主机支持大容量SD存储卡。
- 0: 表示主机不支持大容量SD存储卡。
使用命令CMD8
扩展了ACMD41
的功能; 发送命令ACMD41
时会带有参数HCS,ACMD41
对应的响应为R3(OCR register),包含:VDD电压范围、SD卡容量状态CCS(Card Capacity Status)。如果SD卡没有相应CMD8,那么ACMD41参数HCS会被SD卡忽略。但是,如果卡没有返回对CMD8的响应,主机应该将HCS设置为0 。标准容量的SD卡将忽略HCS。如果HCS设置为0,则大容量SD卡永远不会返回就绪状态(保持Busy Bit为0)。OCR中的Busy Bit被SD卡用来告知主机ACMD41的初始化是否完成。
OCR中的Busy Bit设置为:
- 0:表示该SD卡仍处于初始化状态。
- 1:表示该SD卡初始化已经完成。
主机反复发出ACMD41,直到Busy Bit设置为1。SD卡只在第一个ACMD41检查OCR中的Operational Conditions和HCS位。当重复ACMD41时,主机不得发出除CMD0以外的其他命令。
当卡响应CMD8时,ACMD41的响应中包含CCS字段信息。当SD卡返回Ready(Busy Bit设置为1)时,CCS生效。
CCS(Card Capacity Status)设置为:
- 0: 表示该卡为 Standard Capacity SD Memory Card
- 1: 表示该卡为 High Capacity SD Memory Card
主机对系统中的所有新卡执行相同的初始化顺序,不兼容的卡将被发送到 Inactive 状态。然后主机向每个卡发出命令ALL_SEND_CID
(CMD2),以获得其唯一的卡标识(CID)号。未识别的卡(即处于就绪状态的卡)发送其CID号作为响应(在CMD线上)。在卡发送CID后,它进入识别状态。然后,主机发出CMD3 (SEND_RELATIVE_ADDR)请求卡发布一个新的相对卡地址(RCA),它比CID短,在未来的数据传输模式中用于给卡寻址。一旦接收到RCA,SD卡状态就会变为待机状态。此时,如果主机希望分配另一个RCA号码,它可以通过向卡发送另一个CMD3命令来要求卡发布一个新号码。最后发布的RCA是SD卡的实际RCA号。
3、卡传输模式
在SD卡识别模式结束之前,主机应保持在 fOD (400kHz)频率,因为在SD卡识别模式期间,有些SD卡可能有操作频率限制。在数据传输模式下,主机可以在 fPP (25MHz)频率范围内对卡进行操作。主机发出SEND_CSD(CMD9)以获取与SD卡有关的数据(CSD寄存器),例如块长度、卡的储存容量等。
广播命令SET_DSR
(CMD4)配置所有识别卡的 Driver Stage Register。它根据应用总线的布局(长度)、总线上卡的数量和数据传输频率来编程DSR寄存器。时钟速率也从 fOD 切换到 fPP。SET_DSR
命令是SD卡和主机的一个选项(非必须)。
CMD7用于选择一张SD卡并将其置于传输状态,在同一时刻只能有一张卡处于传输状态。如果先前选择的卡处于传输状态,它与主机的连接将被释放,它将返回到 Stand-by 状态。当CMD7以保留的相对卡片地址“0x0000”发出时,所有卡片都被退回到 Stand-by 状态。
注意:主机预留 RCA = 0x0000 用于退出选择。
下面总结各种数据传输模式之间的关系:
- 所有数据读取命令都可以在任何时候通过停止命令(CMD12)中止。数据传输将终止,SD卡将返回到 Transfer 状态。读命令包括:块读(CMD17)、多块读(CMD18)、发送写保护(CMD30)、发送scr (ACMD51)和读模式的通用命令(CMD56)。
- 所有数据写命令都可以在任何时候通过停止命令(CMD12)中止。在CMD7取消对卡的选择之前,应该停止写命令。写入命令包括:块写入(CMD24和CMD25),程序CSD(CMD27),锁定/解锁命令(CMD42)和写入模式下的常规命令(CMD56)。
- 一旦数据传输完成,SD卡将退出数据写入状态,并移动到 Programming 状态(传输成功) 或 Transfer 状态(传输失败)。
- 如果一个块写操作被停止,并且最后一个块的块长度和CRC是有效的,数据将被编程。
- SD卡可以为块写入提供缓冲。这意味着在前一个块被编程时,下一个块可以被发送到SD卡。如果所有写缓冲区都满了,只要SD卡处于 Programming 状态(见SD卡状态图图4-3),DAT0线就会保持低(BUSY)。
- 写CSD、写保护和擦除没有缓冲选项。这意味着当SD卡忙着处理这些命令中的任何一条时,其他的数据传输命令将不会被接受。只要卡忙且处于 Programming 状态,DAT0线就会保持低电平。
- 当卡在编程时,参数设置命令是不允许的。参数设置命令包括:设置块长度(CMD16),擦除块开始(CMD32)和擦除块结束(CMD33)。
- 当卡在编程时不允许读命令。
- 将另一张卡从 Stand-by 状态转移到 Transfer 状态(使用CMD7)不会终止擦除和编程操作。卡将切换到 Disconnect 状态,将释放DAT线。
- 在 Disconnect 状态下,可以使用CMD7重新选择卡。在这种情况下,卡将转移到 Programming 状态并重新激活占线指示。
- 重置SD卡(使用CMD0或CMD15)将终止任何挂起的或正在进行的编程操作。这可能会破坏卡上的数据内容。防止这种情况发生是主机的责任。
- CMD34-37、CMD50、CMD57预留用于SD命令系统扩容。这些命令的状态转换在每个命令系统规范中都有定义。