实际上,您可能在 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 模式下初始化卡,您应该:
CMD0arg: 0x0, CRC: 0x95(response: 0x01) - 请注意,如果出现0xFF响应或乱码响应,您应该简单地重复此步骤;有关更多信息,请参见下文。
CMD8arg: 0x000001AA, CRC: 0x87(response: 0x01,后跟 arg 的回显,在这种情况下0x000001AA) - 虽然这个命令看起来是可选的,但对于较新的卡来说它是完全强制性的。虽然0x1AA这里是一个常见的 arg 值,但实际上您也可以传递其他值;请参见“表 7-5:CMD8 在 SPI 模式下的卡操作”,第 10 页。108 规格中的详细信息。
3a。CMD55arg: , CRC 0x0: any,实际上(0x65response : 0x01;是every的CMD55前缀 ACMD0x05CMD10x00xF9CMD55ACMD41
3b。ACMD41, arg: 0x40000000, CRC: any,0x77实际上(请注意,此参数假定卡是 HCS 卡,通常是这种情况;对旧卡使用0x0arg [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\$次。有时,乱码的响应是可以的——如果您发送了几次,但响应仍然不是也不是,请尝试继续。如果它有效 - 你很高兴;如果没有 - 它可能已经坏了。CMD0CMD00xFF0x01CMD8
请注意,设置了 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 模式)