使用 SPI 接口初始化 microSD 卡
我在嵌入式设计中使用 microSD 卡。 该卡使用 SPI 接口连接到微控制器。 它适用于我以前使用过的所有卡,但现在我的新卡无法初始化。 该卡是 Transcend 2 GB microSD 卡 (TS2GUSD)。
发送初始时钟序列以切换到 SPI 模式后,我执行以下操作:
CMD0(参数 0,CRC 0x95)-> 响应 0x01 -> OK
CMD8(参数 0x000001AA,CRC 0x87)-> 响应 0x01 0x000001AA -> 表示是SDC V2+卡,支持电压范围2.7V - 3.6V -> OK
那么我应该发送 ACMD41 命令,但是当发送必须在 CMD41 之前的 CMD55(参数 0,CRC 0)时,我得到响应 0x05 -> 非法指挥。 我还尝试发送 CMD1(对于 MMC 卡),但它给出了类似的非法命令响应。 该代码适用于我的 Sandisk 2 GB microSD 卡。
我该如何解决这个问题?
I'm using a microSD card in an embedded design. The card is connected to a microcontroller using the SPI interface. It worked fine for all cards I've used before, but now my new card will not initialize. The card is a Transcend 2 GB microSD card (TS2GUSD).
After sending the initial clock train to switch to SPI mode, I do the following:
CMD0 (Argument 0, CRC 0x95) -> Response 0x01 -> OK
CMD8 (Argument 0x000001AA, CRC 0x87) -> Response 0x01 0x000001AA -> Means it's SDC V2+ card, the voltage range 2.7 V - 3.6 V is supported -> OK
Then I should send the ACMD41 command, but when sending the CMD55 (argument 0, CRC 0) that must precede CMD41, I get response 0x05 -> Illegal Command.
I've also tried to send CMD1 (for MMC cards), but it gives a similar illegal command response. The code works fine with my Sandisk 2 GB microSD card.
How do I fix this problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我好像发现问题了。 当我计算 CMD55 的正确 CRC 并发送它而不是虚拟 CRC 时,命令被接受(结果 0x01)。 如果您查看第 7.2.2 节中的物理层规范 ,它明确表示:
这一系列的Transcend卡似乎并非如此,因此违反了规范。 此外,如果出现 CRC 错误,回复应为 0x09 而不是 0x05。 我尝试使用 CMD59 显式关闭 CRC 检查,但这似乎没有帮助。
=> 为(所有?)命令计算正确的 CRC 可使卡正常工作。
我正在就此事与 Transcend 支持人员联系。 如果我学到一些有用的东西,你就会在这里知道。
请注意,我之前使用过其他 2GB Transcend 卡,但它们是台湾制造的,而新的则是韩国制造的(似乎是三星卡(MMAGR02GUDCA))。
I seem to have found the issue. When I calculate the correct CRC for CMD55 and send that instead of a dummy CRC, the command is accepted (result 0x01). If you look at the physical layer specification in section 7.2.2, it explicitly says that:
This doesn't seem to be the case with this series of Transcend cards, thus violating the specification. Also in case of a CRC error the reply should be 0x09 instead of 0x05. I've tried to explicitly turn off CRC checking with CMD59, but that doesn't seem to help.
=> Calculating the correct CRC for (all?) commands makes the card work.
I'm in contact with Transcend support about this. If I learn something useful I'll you know here.
Note that I used other 2 GB Transcend cards before, but they were made in Taiwan, while the new one is made in Korea (and seems to be a Samsung card (MMAGR02GUDCA)).
我有几乎同样的问题。 当发送ACMD41时,我发送了CMD55,然后发送了CMD41。 CMD55的响应是0x01,表示空闲状态并正在运行初始化过程(我认为这是正常的)。 CMD41 将响应 0x05,表示非法命令。 事实证明,我的特定卡默认执行 CRC 检查,即使在 SPI 模式下也是如此,并将 CRC 错误误报为非法命令(即,它不遵循 SD 规范)。 当我计算正确的 CRC 时,它工作得很好。 这是我使用的 CRC7 计算代码,它对我来说效果很好:
https://github.com/hazelnusse/crc7
除非您小心地禁用了 CRC 检查,否则我认为最好假设它没有禁用,并确保为每个命令帧计算正确的 CRC。 据我所知,有些卡在 SPI 模式下默认禁用它,而另一些卡则启用它,尽管 SD 规范规定在 SPI 模式下默认应禁用它(CMD8 除外)。
I had almost the same issue. When sending ACMD41, I sent CMD55 followed by CMD41. The response for CMD55 was 0x01, indicating idle state and running the initialization process (this is normal, I think). CMD41 would respond with 0x05, indicating illegal command. It turns out that my particular card does the CRC check by default, even in SPI mode, and misreports CRC errors as illegal commands (i.e., it doesn't follow the SD spec). When I calculate the proper CRC, it works fine. Here is the CRC7 calculation code I used, it has worked well for me:
https://github.com/hazelnusse/crc7
Unless you have taken care to disable CRC checking, I think it is probably best to assume it isn't disabled and make sure you calculate the proper CRC for each command frame. From what I can tell, some cards disable it by default in SPI mode and others enable it, even though the SD specification states it should be disabled by default in SPI mode except for CMD8.
您说您使用
CRC 0
来处理失败的命令。 我假设您的意思是您将整个最后一个字节作为0x00
发送。 请注意,CRC7 只是最后一个字节的前 7 位 - 称为end bit
的最后一位应始终为1
。 因此,如果您将0x00
作为最后一个字节发送,并以0
作为最后一位,则失败是可以理解的,甚至错误代码也是有意义的。 如果您发送1
作为最后一位,它应该可以工作,即。 使用0x01
或0xFF
作为最后一个字节。You said you used
CRC 0
for the failing command. I assume that you meant that you sent the whole last byte as0x00
. Note that the CRC7 is only the first 7 bits of the last byte - the last bit calledend bit
should always be1
. So if you were sending0x00
as the last byte, with0
as the last bit, the failure would be understandable, and even the error code would make sense. If you send1
as the last bit, it should work, ie. use something like0x01
or0xFF
as the last byte.这是正常的,可能是用于产生擦除电压的内部电荷泵需要比平时更长的时间才能准备好......您必须坚持使用 CMD55+ACMD41 组合,直到初始化完成。
CMD58 还可以帮助您检查是否提供正确的电压电平(有时插座存在接触问题)。
It's normal, it's likely the internal charge-pump used to make erase voltage that takes longer than usual to be ready... you have to insist on the CMD55+ACMD41 combo until initialization finishes.
The CMD58 could also help you to check if you're supplying correct voltage levels (sometimes sockets have contact problems).
单独发送带片选(0)的 CMD0 不会在 SPI 模式下初始化卡。 这仅设置 SPI 模式。
在 ACMD41 返回接受之前,卡不会初始化。 那么CRC默认是关闭的。
Sending CMD0 with chip select(0) alone does not initialize the card in SPI mode. This only sets SPI mode.
Card is not initialized until ACMD41 returns accepted. Then CRC is off by default.
在 CMD55(0xFF 发送+接收)之后和 CMD41 之前插入几个虚拟 SPI 周期。
我必须对我的旧测试卡(16MB Panasonic 和 Sandisk 64MB)执行此操作。
注意:我意识到我参加聚会已经很晚了,但我希望它可以对将来的人有所帮助。
Insert several dummy SPI cycles after CMD55 (0xFF sent+received) and before CMD41.
I had to do this for both my old test cards - 16MB Panasonic and Sandisk 64MB.
Note: I realize I'm quite late to the party, but I'm hoping it may help someone in future.