我有一个基于ST Microelectronics SDIO微控制器的定制板,其中的SDIO卡插在微控制器的STM32F103VE总线上。电气连接完全按照在STM3210E-EVAL board schematics中找到的,检查和再检查,所以我有很强的信心,他们是正确的。不幸的是,我没有那个评估板来测试我所经历的是不是一个硬件问题,但它看起来不是。对于下面的测试,我使用的是最近购买的金斯顿2 GB MicroSD卡(型号为MBLYG22/2 GB)(因此它应该符合最新的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,但我还是将逻辑分析仪连接到电路上,以验证其正确性。我正在使用一个web应用程序(对不起,不能链接,因为我是一个新用户,但是只在谷歌上搜索"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失败并在路上,我可以只发送第二个吗?或者会有任何负面影响吗?即使这解决了问题,我也非常想知道为什么CRC校验失败了,因为我不认为我做错了什么。
发布于 2010-11-29 22:43:09
我找到问题了。在我必须修改代码以刷新CMD8响应的缓冲区,以便CMD55读取正确的响应之后,我所做的每个测试都将逻辑分析仪连接到电路上。删除逻辑分析器后,代码开始工作--可能是向代码行中注入了噪声。不需要延迟,但为了遵循规范,我在CMD0之前添加了一个74+时钟周期延迟。
发布于 2010-11-29 02:14:15
AFAIK,错误已在最新版本(3.4.0)的外围库中修复。
https://stackoverflow.com/questions/4298178
复制相似问题