为什么通过 SPI 将 CMD58 发送到我的 Class 10 SD return 0x01 而不是 0x00?
Why does sending CMD58 over SPI to my Class 10 SD return 0x01 instead of 0x00?
我正在尝试使用 SPI 总线和 STM32F4 探索板初始化 SD 卡。我主要依靠 Elm Chan 在示例代码中对 disk_initialize 函数的实现来构建我自己的实现。不幸的是,我 运行 遇到一个问题,即在初始化过程中向 SD 卡发送 CMD58 return 结果为 0x01,这意味着 SD 卡处于空闲状态。但是,我仍然看到 SD 卡接下来的四个字节为 0x00、0xFF、0x80、0x00,这是 R3 响应的正确格式。但是,我不确定我是否可以将这四个字节作为我的 OCR。
截至目前,我已经尝试忽略 SD 卡处于空闲状态并简单地尝试使用接下来的四个字节作为 OCR,但代码似乎在安装过程中的其他点失败从 OCR 获取的卡片。
if (Timer1 && SD_SendCmd(CMD58, 0) == 0) {
for (n = 0; n < 4; n++) {
ocr[n] = SPI_RxByte();
}
type = (ocr[0] & 0x40) ? 6 : 2;
}
上面的代码段是我第一次看到空闲响应的地方。 SD_SendCmd 是我将 CMD58 发送到 SD 卡的地方,也是我收到 0x01 作为五字节响应的最左边字节的地方。因为我没有收到 0x00,这表明 SD 卡对传递给它的命令没有问题,代码中断了初始化过程并且 return 出现了错误。我将非常感谢任何帮助解决这个问题,因为我已经被这个 0x01 return 值难住了很长一段时间了。谢谢!
所以我能够弄清楚问题所在。原来我用的卡是SDHC卡,HC是高容量的意思。根据简化的 SD 卡规范,在命令传输结束时发送的 CRC 必须将最低有效位设置为 1。因此,在任何传输之前将 CRC 与 0x01 进行或运算让我初始化和使用任何类型的 SD 卡。所以我遇到的问题不是来自 CMD58,而是我一般如何处理 CRC。有趣的是,不对 CRC 进行 ORing 似乎可以很好地处理非 high-capacity SD 卡。但 ORing 与 0x01 的 CRC 似乎适用于所有卡(至少就我测试而言)。
关于 CRC 与 0x01 的或运算,这不是 CRC,而是停止位,CRC 的类型为 CRC7,位于命令中字节 #6 的位 1:7。按照规范,即使不需要CRC校验,停止位也必须一直为1。
我正在尝试使用 SPI 总线和 STM32F4 探索板初始化 SD 卡。我主要依靠 Elm Chan 在示例代码中对 disk_initialize 函数的实现来构建我自己的实现。不幸的是,我 运行 遇到一个问题,即在初始化过程中向 SD 卡发送 CMD58 return 结果为 0x01,这意味着 SD 卡处于空闲状态。但是,我仍然看到 SD 卡接下来的四个字节为 0x00、0xFF、0x80、0x00,这是 R3 响应的正确格式。但是,我不确定我是否可以将这四个字节作为我的 OCR。
截至目前,我已经尝试忽略 SD 卡处于空闲状态并简单地尝试使用接下来的四个字节作为 OCR,但代码似乎在安装过程中的其他点失败从 OCR 获取的卡片。
if (Timer1 && SD_SendCmd(CMD58, 0) == 0) {
for (n = 0; n < 4; n++) {
ocr[n] = SPI_RxByte();
}
type = (ocr[0] & 0x40) ? 6 : 2;
}
上面的代码段是我第一次看到空闲响应的地方。 SD_SendCmd 是我将 CMD58 发送到 SD 卡的地方,也是我收到 0x01 作为五字节响应的最左边字节的地方。因为我没有收到 0x00,这表明 SD 卡对传递给它的命令没有问题,代码中断了初始化过程并且 return 出现了错误。我将非常感谢任何帮助解决这个问题,因为我已经被这个 0x01 return 值难住了很长一段时间了。谢谢!
所以我能够弄清楚问题所在。原来我用的卡是SDHC卡,HC是高容量的意思。根据简化的 SD 卡规范,在命令传输结束时发送的 CRC 必须将最低有效位设置为 1。因此,在任何传输之前将 CRC 与 0x01 进行或运算让我初始化和使用任何类型的 SD 卡。所以我遇到的问题不是来自 CMD58,而是我一般如何处理 CRC。有趣的是,不对 CRC 进行 ORing 似乎可以很好地处理非 high-capacity SD 卡。但 ORing 与 0x01 的 CRC 似乎适用于所有卡(至少就我测试而言)。
关于 CRC 与 0x01 的或运算,这不是 CRC,而是停止位,CRC 的类型为 CRC7,位于命令中字节 #6 的位 1:7。按照规范,即使不需要CRC校验,停止位也必须一直为1。