11

我查看了 Stack Overflow question Initialization of a microSD card using an SPI interface,但没有看到任何与我的问题相匹配的答案(也就是说,我还没有尝试过的事情)。

我有一个类似的问题,我试图通过微控制器的 SPI 接口(特别是HC908)访问 SD 卡。我已经尝试遵循物理层简化规范 v2.00 中的流程图,它似乎在 Transcend 1 GB 和 2 GB 以及 AE&C 1 GB 卡上正确初始化。但是我在相机上使用的旧卡中的其他三张随机卡上遇到了问题。

我的代码都是 HC908 汇编程序。我确定了 SPI 时钟线的范围,在初始化期间它的运行频率约为 350 kHz(HC908 在我的 100 - 400 kHz 窗口内的低 MCU 时钟速度下提供的唯一速度倍增器)。

以下是未完成我的初始化例程的三张卡的结果(全部连续完成,无需更改任何代码或时序参数):

Canon 16Meg card (labeled as SD):
Set card select high
Send 80 SPI clock cycles (done by writing 0xFF 10 times)
Set card select low
Send CMD0 [0x400000000095] and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x01 (indicates idle)
Send CMD8 [0x48000001AA87] and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x05 (idle and illegal command)
Because illegal command set local flag to indicate v1 or MMC card
Send CMD58 [0x7A00000000FD] and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x05 (idle and illegal command)
because illegal command branch to error routine
Send CMD13 [0x4D000000000D] (show status buffer) and Loop up to 8 times waiting for high bit on response to go low
R1= 0x05 (idle and illegal command)

非法命令标志卡住了吗?我应该在 CMD8 之后做些什么来清除那个标志吗?

SanDisk UltraII 256Meg
Set card select high
Send 80 SPI clock cycles (done by writing 0xFF 10 times)
Set card select low
Send CMD0 [0x400000000095] and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x01 (idle)
Send CMD8 [0x48000001AA87] and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x05 (idle and illegal command)
Because illegal command set local flag to indicate v1 or MMC card
Send CMD58 [0x7A00000000FD] and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x01 (idle)
Send 0xFF 4 times to read OCR
OCR = 0xFFFFFFFF
Send CMD55 [0x770000000065] (1st part of ACMD41) and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x01 (idle)
Send CMD41 [0x6900000000E5] (2nd part of ACMD41) and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x05 (idle and illegal command)
Because illegal command, assume card is MMC
Send CMD1 [0x4100000000F9] (for MMC) and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x05 (idle and illegal command)
Repeat the CMD1 50 times (my arbitrary number to wait until idle clears)
Every R1 response is 0x05 (idle and illegal command)

为什么OCR全是F?似乎一点都不合适。另外,为什么 ACMD41 和 CMD1 响应非法命令?CMD1 失败是因为卡在 CMD55 之后等待有效的 ACMD,即使有非法命令响应?

SanDisk ExtremeIII 2G:
Set card select high
Send 80 SPI clock cycles (done by writing 0xFF 10 times)
Set card select low
Send CMD0 [0x400000000095] and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x01 (idle)
Send CMD8 [0x40000001AA87] and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x7F (??? My loop shows the responses for each iteration and I got 0xFF 0xFF 0xC1 0x7F... is the card getting out of sync?)
Send CMD58 [0x7A00000000FD] and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x01 (idle and back in sync)
Send 0xFF 4 times to read OCR
OCR = 0x00FF80
Send CMD55 [0x770000000065] (1st part of ACMD41) and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x5F (??? loop responses are 0xFF 0xFF 0xF0 0x5F... again out of sync?)
Send CMD41 [0x6900000000E5] (2nd part of ACMD41) and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x05 (idle and illegal command, but back in sync???)
Because illegal command, assume card is MMC
Send CMD1 [0x4100000000F9] (for MMC) and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x7F (??? loop responses are 0xFF 0xFF 0xC1 0x7F... again out of sync?)
Repeat CMD1 and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x01 (idle)
Repeat CMD1 and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x7F (??? loop responses are 0xFF 0xFF 0xC1 0x7F... again out of sync?)
Repeat CMD1 and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x00 (out of idle)
Send CMD9 [0x4900000000AF] (get CSD) and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x3F (??? loop responses are 0xFF 0xFF 0xC1 0x3F... again out of sync?)
Code craps out because Illegal command bit is high.

那张卡到底有什么问题?

有时它是同步的,有时则不是。(上述模式可重复的。)我已经确定了这个范围,我没有看到 MOSI/MISO 传输之间有任何流氓时钟周期。

4

3 回答 3

23

好的...我发现了我的问题。对于遇到此问题的其他任何人,请务必记住0xFF在收到回复后发送额外信息。这为卡提供了额外的八个时钟周期来为下一个命令做好准备。有些卡似乎不需要它(例如我正在使用的 Transcends),但其他卡则需要它。

实际上,我在“写命令”例程的开头放置了一个简单的循环,该循环一直发送0xFF到它0xFF作为响应,这样我就不必去所有不同的地方读取响应以确保我添加了额外的发送0xFF. 因为就(通常)在 SPI 模式下关注 SD 卡而言,如果没有时钟周期进入,时间就会静止。

我注意到但尚未找到答案的一件事(但到目前为止它并没有伤害任何东西),在我阅读了 CSR 的 16 个字节之后,似乎还有另外 2 个字节的 non-0xFF出来了。 ..那是CRC16吗?奇怪,因为 CSR 内置了 CRC……

于 2010-03-03T21:46:36.117 回答
3

如果您启用了 CRC(使用 CMD59),那么是的,数据块将附加 CRC16。

有关详细信息,请参阅“物理层简化规范版本 2.00”、“总线传输保护”和“数据读取”章节。

于 2010-08-16T10:33:17.750 回答
2

这很重要:我在 SD/MMC 卡上遇到了很多麻烦,直到我发现我必须选择一个工作电压。为此,您可以发送 ACMD41 并设置为您为卡提供电压的位。注意:只能选择一个位。如果您不选择电压或选择多个电压,它将保持在空闲状态循环,并且永远不会在某些 SD 卡上退出。

即:如果你的ACMD41一直发送响应0x01,你没有选择电压。电压在 ACMD41 的 32 位参数位 23...8 中。对于 3.2V ... 3.3V,这是第 20 位,例如,您可以:

acmdSDAppOpCond[2] = (1 << (20 & 7));           /* 3.2V .. 3.3V */

那是十六进制值 0x10,所以你的 ACMD41 看起来像这样... 0x69 0x40 0x10 0x00 0x00 0xCD ...或者如果它是 SDSC 卡... 0x69 0x00 0x10 0x00 0x00 0x5F

这是最常见值的简短(且不完整)表:

Bit23: 3.5V..3.6V
Bit22: 3.4V..3.5V
Bit21: 3.3V..3.4V
Bit20: 3.2V..3.3V
Bit19: 3.1V..3.2V
Bit18: 3.0V..3.1V
Bit17: 2.9V..3.0V
Bit16: 2.8V..2.9V
Bit15: 2.7V..2.8V

您不必任何时间点将 CS 切换为高电平。你可以一直保持在低位。

于 2014-04-24T10:19:16.927 回答