实际上,您可能在 SD 初始化中找到的大多数信息/代码要么过时,要么不准确,因为它早于 SDHC 和 SDXC 多年。如今,该过程更加复杂,因为它迫使您以向后兼容的方式处理旧硬件。
首先,正如其他人所提到的,选择一个较低的初始时钟速率(一般在 100 kHz - 400 kHz 范围内;如果可能,使用 400 kHz);如果设备允许,您稍后可以切换到更高的时钟。虽然新卡可以安全地承受 MHz 级时钟,但旧卡会抱怨(即无法通信或返回垃圾)。
接下来是你不应该用它CMD1
来初始化 SD/SDHC/SDXC 卡,除非你的卡不能识别CMD55
/ ACMD41
;如 SD 卡规范中所述:
在任何情况下都不建议使用 CMD1,因为主机可能难以区分 MultiMediaCard 和 SD 存储卡。
如果您向它们发出一些控制器(主要是更新和更高容量的卡),它们只会停留在空闲状态CMD1
。你应该先CMD8 0x1AA
在reset( CMD0
)后发出,然后再尝试使用CMD55 + ACMD41
。当且仅当失败时,使用CMD1
.
tl;博士要在 SPI 模式下初始化卡,您应该:
CMD0
arg: 0x0
, CRC: 0x95
(response: 0x01
) - 请注意,如果出现0xFF
响应或乱码响应,您应该简单地重复此步骤;有关更多信息,请参见下文。
CMD8
arg: 0x000001AA
, CRC: 0x87
(response: 0x01
,后跟 arg 的回显,在这种情况下0x000001AA
) - 虽然这个命令看起来是可选的,但对于较新的卡来说它是完全强制性的。虽然0x1AA
这里是一个常见的 arg 值,但实际上您也可以传递其他值;请参见“表 7-5:CMD8 在 SPI 模式下的卡操作”,第 10 页。108 规格中的详细信息。
3a。CMD55
arg: , CRC 0x0
: any,实际上(0x65
response : 0x01
;是every的CMD55
前缀 ACMD
0x05
CMD1
0x0
0xF9
CMD55
ACMD41
3b。ACMD41
, arg: 0x40000000
, CRC: any,0x77
实际上(请注意,此参数假定卡是 HCS 卡,通常是这种情况;对旧卡使用0x0
arg [CRC 0xE5
])。如果 response 是0x0
,你就可以了;如果是0x01
,转到 3a;如果是0x05
,请参见上面的注释(在 3a 中);如果两者都不是,则说明有问题(另见下文)。
大多数卡片需要重复步骤 3a/3b(或CMD1
旧卡片),通常至少重复一次,即使您在它们之间等待一段时间;即实际顺序是CMD0
/ CMD8
/ CMD55
/ ACMD41
/ CMD55
/ ACMD41
(或CMD0
/ CMD8
/ CMD1
/ CMD1
) - 可以肯定的是,尝试CMD55
/ ACMD41
(或者CMD1
如果你0x05
从他们那里得到)\$n\$次(在你的理由中选择\$n\$ ;它是实际上,如果设备刚打开电源,则必须等待几百毫秒是很常见的,所以瞄准那个),如果你愿意,尝试之间会有小的延迟,如果响应则假设失败0
不出现(即如果设备由于某种原因处于空闲模式)。此外,如果设备之前处于某种“奇怪”状态(例如挂断、S̲S̲ 置低 [高]、某些引脚上出现过压/欠压等),接收0xFF
来自的情况很常见 - 只需给它一些时间,冲洗并重复\$n\$次。有时,乱码的响应是可以的——如果您发送了几次,但响应仍然不是也不是,请尝试继续。如果它有效 - 你很高兴;如果没有 - 它可能已经坏了。CMD0
CMD0
0xFF
0x01
CMD8
请注意,设置了 MSB 但0xFF
通常不表明您的 SPI 时钟发生了变化的响应(例如,由于 Vcc 下降,这在您进行 SD 热插拔时经常发生)。要修复它,您可以尝试完全重置设备(电源开/关、置低/置位 S̲S̲ 等);它通常有效。
此外,规范说
在最后一次 SD 存储卡总线事务之后,主机需要在关闭时钟之前提供 8(八)个时钟周期让卡完成操作。
它可以在没有它的情况下工作,但由于 8 个周期 = 1 个 SPI 输出字节,它不会造成太大伤害,拥有它就很好。
请注意,您应该至少在每次之前和之后都将 S̲S̲(又名 CS)断言为低电平CMD
- 这是完全强制性的CMD0
(如果没有它,设备将无法打开),实际上,CMD
如果您有标准,则对于所有其他 s都是必需的- 兼容的 SD 卡。似乎将卡的 S̲S̲ 永久连接到 GND如果卡是您的主机将连接到的唯一 SPI 客户端,这是一个好主意,因为它可以节省您的 uC 输出引脚和完全通过代码管理它的需要,并且因为卡应该假设它已全部选中的时间。实际上,有些卡(如果不是大多数卡)实际上期望从高到低的斜率打开,而不是简单地检测到低,因此如果您根本不切换 S̲S̲ 位,然后要么滞后就会生气时钟或吐垃圾;有些(通常是较新的)卡应该可以工作,有些(旧的)可能不行,YMMV(又一次)。尽管如此,对于任何更强大的 SPI 配置(>1 个从设备),请记住在与给定 SD 卡进行任何实际事务之前将引脚置为低电平。
此外,虽然规范说只有CMD0
并且CMD8
应该在 SPI 模式下具有 CRC,但某些 SD 卡(如 Transcend 卡)似乎需要适当的 CRC 来处理CMD55
/ ACMD41
- 如果您想安全起见,只需为它们使用预先计算的值。
此外,虽然 SPI 本身不需要上拉/下拉,但在 MISO 上进行 47k 上拉可能是个好主意;某些设备在特定情况下(例如未初始化)将其 DO 引脚保持为高阻态,并且浮动引脚始终可能是奇怪问题的根源。如果你的 uC 有 3.3 Vcc,你可以使用内部上拉;如果是 5V,除非你的 MISO 线已经有适当的 5->3.3V 逻辑转换,否则不要这样做。
进一步阅读:
如何使用 MMC/SDC
SD 规范第 1 部分简化物理层简化规范- 最重要的是第6.4.1节和第7.2.1 节模式选择和初始化,图 7-1:SD 存储卡状态图(SPI 模式)