我有一个基于ST Microelectronics STM32F103VE微控制器的定制电路板,MiniSD卡插在微控制器的SDIO总线上。电气连接完全按照STM3210E-EVAL board schematics中的要求进行,检查并重新检查,因此我非常有信心他们是正确的。不幸的是,我没有那个评估板来测试我遇到的是硬件问题,但似乎并非如此。对于下面的测试,我使用的是最近购买的金士顿2 GB MicroSD卡(型号MBLYG2 / 2GB)(因此它应符合最新的SD卡规格)和随附的MicroSD到MiniSD适配器;尚未使用任何其他卡进行测试。
我正在遵循SD卡物理层简化规范来了解正在发生的事情。我正在使用的代码是ST Micro为该微控制器提供的标准外设库附带的示例SDIO代码。它首先发送CMD0(GO_IDLE_STATE),然后发送CMD8(SEND_IF_COND),然后发送ACMD41(SD_SEND_OP_COND),这是通过发送CMD55(APP_CMD)然后发送CMD41来完成的。时钟线的时钟频率为400 kHz,作为调试工作的一部分,我在CMD0和CMD8之间增加了大约100个时钟周期的延迟,因为我已经读到了需要的地方,至少在SPI中运行时模式。除了下面提到的修改之外,代码与示例代码完全相同。
当我第一次尝试运行示例代码时,CMD55遇到了一个问题,原因是微控制器正在缓冲对CMD8的响应,但示例代码没有检索CMD8的响应,因此在检查对CMD55的响应时,代码实际上是在查看对CMD8的响应,并对此感到不安。我通过在发送CMD55之前清除微控制器的SDIO外设上的CMDREND标志来解决这个问题,所以当代码检查了对CMD55的响应时,它不再缓冲CMD8的响应。
下一个问题,也就是我目前所处的问题,是在对CMD55的响应中,设置了卡状态字段(COM_CRC_ERROR)的第23位,这表示上一个命令的CRC校验失败,具体取决于规范。虽然微控制器自动计算CRC,但我将逻辑分析仪连接到电路以验证它是否正确。我正在使用网络应用程序(抱歉,无法链接,因为我是新用户,但只是Google用于“CRC ghsi”并且这是第一个结果)验证CRC,使用多项式x ^ 7 + x ^根据规格3 + 1。这是逻辑分析仪输出,由我格式化和评论:
// uC sends CMD0, CRC OK, no response:
01 000000 00000000000000000000000000000000 1001010 1
// uC sends CMD8, CRC OK, check byte = 0xAA:
01 001000 00000000000000000000000110101010 1000011 1
// SD card responds to CMD8, CRC OK, check byte echoed back = 0xAA:
00 001000 00000000000000000000000110101010 0001001 1
// uC sends CMD55, CRC OK:
01 110111 00000000000000000000000000000000 0110010 1
// SD card responds to CMD55, CRC OK, note card status bits 23, 8 and 5 set;
// bit 23 = COM_CRC_ERROR, bit 8 = READY_FOR_DATA and bit 5 = APP_CMD:
00 110111 00000000100000000000000100100000 0000100 1
另请注意,如果我在上述交换后立即第二次尝试CMD55,则第23位未设置:
// uC sends CMD55, CRC OK:
01 110111 00000000000000000000000000000000 0110010 1
// SD card responds to CMD55, CRC OK, bits 8 and 5 still set but 23 not set:
00 110111 00000000000000000000000100100000 1000001 1
请注意,我尝试在发送CMD55之前两次发送CMD8,但没有区别,第一个CMD55总是返回第23位设置。我每次尝试都可以重现这一点,所以我不相信这是毛刺或噪音的问题。考虑到CRC是由微控制器本身计算的,它们看起来正如外部实体(逻辑分析仪)所见,并且已经在我上面提到的网站上得到验证,我不知道卡的CRC校验是如何失败的。
这是以某种方式预期的吗?也许我应该在每个命令之间等待一定数量的时钟周期(在某个地方我读它应该是8个周期,我相信我尊重它)?如果第一个CMD55失败并且在我的路上,我可以发送第二个CMD55,还是会产生任何负面影响?即使这样可以解决问题,我也非常想知道CRC检查失败的原因,因为我认为我没有做错任何事。
答案 0 :(得分:5)
我发现了问题。在我必须修改代码以刷新CMD8响应的缓冲区之后,CMD55读取正确的响应,我做的每个测试都将逻辑分析仪连接到电路。删除逻辑分析仪后,代码开始工作 - 可能是在线路中注入噪声。不需要延迟,但只是为了遵循规范,我在CMD0之前增加了74个时钟周期的延迟。
答案 1 :(得分:0)
AFAIK,在外设库的最新版本(3.4.0)中修复了这些错误。