我在嵌入式设计中使用microSD卡。该卡通过SPI接口连接到微控制器。它适用于我之前使用的所有卡,但现在我的新卡不会初始化。该卡是Transcend 2 GB microSD卡(TS2GUSD)。
在发送初始时钟串以切换到SPI模式后,我执行以下操作:
CMD0(参数0,CRC 0x95) - >响应0x01 - >确定
CMD8(参数0x000001AA,CRC 0x87) - >响应0x01 0x000001AA - >意味着它是SDC V2 +卡,支持2.7 V - 3.6 V的电压范围 - >确定
然后我应该发送ACMD41命令,但是当发送必须在CMD41之前的CMD55(参数0,CRC 0)时,我得到响应0x05 - >非法指挥。 我也尝试发送CMD1(用于MMC卡),但它提供了类似的非法命令响应。该代码适用于我的Sandisk 2 GB microSD卡。
如何解决此问题?
答案 0 :(得分:16)
我似乎找到了这个问题。当我为CMD55计算正确的CRC并发送它而不是伪CRC时,接受该命令(结果0x01)。如果你看一下7.2.2节中的the physical layer specification,它明确地说:
默认情况下,SPI接口在CRC OFF模式下初始化。 (命令CMD0和CMD8除外)。
这一系列的Transcend卡似乎并非如此,因此违反了规范。同样在CRC错误的情况下,回复应该是0x09而不是0x05。我试图用CMD59明确关闭CRC校验,但这似乎没有帮助。
=>为(所有?)命令计算正确的CRC会使卡工作。
我与Transcend有关此事的支持。如果我学到了一些有用的东西,我会在这里知道。
请注意,之前我使用过其他2 GB的Transcend卡,但它们是在台湾制造的,而新的是在韩国制造的(并且似乎是三星卡(MMAGR02GUDCA))。
答案 1 :(得分:2)
我几乎有同样的问题。发送ACMD41时,我发送CMD55,然后发送CMD41。 CMD55的响应是0x01,表示空闲状态并运行初始化过程(这是正常的,我认为)。 CMD41将以0x05响应,表示非法命令。事实证明,我的特定卡默认情况下进行CRC校验,即使在SPI模式下也是如此,并且错误地将CRC错误报告为非法命令(即,它不遵循SD规范)。当我计算正确的CRC时,它工作正常。这是我使用的CRC7计算代码,它对我来说效果很好:
https://github.com/hazelnusse/crc7
除非您已经注意禁用CRC校验,否则我认为最好不要假设它没有被禁用,并确保为每个命令帧计算正确的CRC。据我所知,有些卡在SPI模式下默认禁用它,其他卡启用它,即使SD规范声明它应该在SPI模式下默认禁用,除了CMD8。
答案 2 :(得分:2)
您说您使用CRC 0
作为失败命令。我假设您的意思是您将整个最后一个字节发送为0x00
。请注意,CRC7只是最后一个字节的前7位 - 最后一位称为end bit
的位应始终为1
。因此,如果您将0x00
作为最后一个字节发送,并将0
作为最后一位,那么失败将是可以理解的,甚至错误代码也是有意义的。如果您发送1
作为最后一位,它应该可以工作,即。使用0x01
或0xFF
之类的内容作为最后一个字节。
答案 3 :(得分:1)
这是正常的,可能是内部电荷泵用于使擦除电压比平常花费更长时间准备好......你必须坚持使用CMD55 + ACMD41组合,直到初始化结束。
CMD58还可以帮助您检查是否提供了正确的电压水平(有时插座有接触问题)。
答案 4 :(得分:1)
单独使用片选(0)发送CMD0不会在SPI模式下初始化卡。这仅设置SPI模式。 在ACMD41退回接受之前,卡片未初始化。然后默认关闭CRC。
答案 5 :(得分:0)
在CMD55(发送+接收0xFF)之后和CMD41之前插入几个虚拟SPI周期。
我必须为两个旧测试卡(松下16MB和Sandisk 64MB)执行此操作。
注意:我意识到我参加聚会已经很晚了,但我希望它将来对某人有帮助。