我正在尝试初始化 SDHC(大容量)的 microSD 卡。我从 CMD0 和 CMD8 得到逻辑响应。CMD8 正确地回显了我的论点(0x1AA)。
当我发送 ACMD41 时,我期待 R3 响应设置了繁忙位(根据物理层简化规范,版本 8.00)。相反,我反复从 CMD55 和 ACMD41 获得 0x01 的 R1 响应,直到卡完全停止响应任何命令。
我在面包板上使用 Arduino Nano 33 IoT,microSD 卡插入Maxmoral SPI microSD 卡适配器。我的 Arduino 的正极 3.3V 端子上有一个 10 欧姆的电阻。读卡器的 SPI 输入和输出进入 arduino 上的数字引脚。
它是一张 SanDisk 16 GB microSDHC 卡。
我假设这不是硬件或时间问题,因为像 CMD8 和 CMD58 这样的命令似乎可以工作(直到我发出 ACMD41)。我在任何命令之前发送 0xFF,如果没有它,我不会收到任何命令的响应。我在任何命令之前将 CS 引脚设置为低电平,并在接收数据后设置回高电平。
可能是什么问题?我对 ACMD41 的论点不正确吗?在我看来,该卡出于某种原因拒绝了主机。
这些是我为 ACMD41 测试过的论点:
0x00 0x00 0x00 0x00 // All bits off
0x40 0x00 0x00 0x00 // HCS bit on, everything else off
0x40 0xFF 0x80 0x00 // HCS bit on, voltages that are echoed back by CMD58
0x40 0x10 0x00 0x00 // HCS bit on, voltage 3.2-3.3 V
0x40 0x20 0x00 0x00 // HCS bit on, voltage 3.3-3.4 V
0x40 0x30 0x00 0x00 // HCS bit on, voltage 3.2-3.4 V
这是用于初始化卡的代码:
pinMode(MISO, INPUT);
pinMode(CS, OUTPUT);
pinMode(SCLK, OUTPUT);
pinMode(MOSI, OUTPUT);
digitalWrite(CS, HIGH);
unsigned char dummy = 0xFF;
frame_commander.clock_manager.CLOCK_TIME = FAST_CLOCK; // #define FAST_CLOCK 1.0 / 200000.0 * 1000.0
frame_commander.r_type = 1;
frame_commander.cmd = CMD0; // unsigned const char CMD0 = 0x40;
frame_commander.arg1 = 0x00;
frame_commander.arg2 = 0x00;
frame_commander.arg3 = 0x00;
frame_commander.arg4 = 0x00;
frame_commander.crc = INIT_CRC; // unsigned const char INIT_CRC = 0x95;
/*
*A binary number of 80 1's is too large to store in an unsigned char.
*/
for (int i = 0; i < 10; i++) {
frame_commander.send_data(dummy, 8);
}
/*
*Sets to SPI mode
*/
frame_commander.send_command_frame(); // Card responds 0x01 (in idle state)
Serial.println(frame_commander.recieved_data, HEX);
frame_commander.r_type = 3;
frame_commander.cmd = CMD8; // unsigned const char CMD8 = 0x48;
frame_commander.arg1 = 0x00;
frame_commander.arg2 = 0x00;
frame_commander.arg3 = 0x01;
frame_commander.arg4 = 0xAA;
frame_commander.crc = CMD8_CRC;
frame_commander.send_command_frame();
Serial.println(frame_commander.recieved_data, HEX); // Card responds 0x01
Serial.println(frame_commander.recieved_byte2, HEX);
Serial.println(frame_commander.recieved_byte3, HEX);
Serial.println(frame_commander.recieved_byte4, HEX); // Card echoes 0x01
Serial.println(frame_commander.recieved_byte5, HEX); // Card echoes 0xAA
/*
*Initializes card
*/
frame_commander.r_type = 1;
frame_commander.arg1 = 0x00;
frame_commander.arg2 = 0x00;
frame_commander.arg3 = 0x00;
frame_commander.arg4 = 0x00;
while (frame_commander.recieved_data != 0) {
frame_commander.cmd = CMD55; // unsigned const char CMD55 = 0x77;
frame_commander.r_type = 1;
frame_commander.arg1 = 0x00;
frame_commander.arg2 = 0x00;
frame_commander.arg3 = 0x00;
frame_commander.arg4 = 0x00;
frame_commander.send_command_frame();
frame_commander.cmd = ACMD41; // unsigned const char ACMD41 = 0x69;
frame_commander.r_type = 3;
frame_commander.arg1 = 0x40;
frame_commander.arg2 = 0x00;
frame_commander.arg3 = 0x00;
frame_commander.arg4 = 0x00;
frame_commander.send_command_frame();
Serial.print("Did recieve data: ");
Serial.println(frame_commander.did_recieve_data); // Card responds 0x01
Serial.println(frame_commander.recieved_data, BIN); // Card responds 0xFF
Serial.println(frame_commander.recieved_byte2, BIN); // Card responds 0xFF
Serial.println(frame_commander.recieved_byte3, BIN); // Card responds 0xFF
Serial.println(frame_commander.recieved_byte4, BIN); // Card responds 0xFF
Serial.println(frame_commander.recieved_byte5, BIN); // Card responds 0xFF
}
// Is never reached
Serial.println("Completed initialization.");
Serial.println(frame_commander.recieved_data, BIN);
Serial.println(frame_commander.recieved_byte2, BIN);
Serial.println(frame_commander.recieved_byte3, BIN);
Serial.println(frame_commander.recieved_byte4, BIN);
Serial.println(frame_commander.recieved_byte5, BIN);
frame_commander.arg1 = 0x00;
frame_commander.arg2 = 0x00;
frame_commander.arg3 = 0x00;
frame_commander.arg4 = 0x00;
frame_commander.cmd = CMD58;
frame_commander.crc = CMD58_CRC;
frame_commander.r_type = 3;
frame_commander.send_command_frame();
Serial.println("CMD58 sent");
Serial.println(frame_commander.recieved_data, BIN);
Serial.println(frame_commander.recieved_byte2, BIN);
Serial.println(frame_commander.recieved_byte3, BIN);
Serial.println(frame_commander.recieved_byte4, BIN);
Serial.println(frame_commander.recieved_byte5, BIN);
这是发送单个命令的代码:
digitalWrite(CS, LOW);
send_data(0xFF, 8);
send_data(cmd, 8);
send_data(arg1, 8);
send_data(arg2, 8);
send_data(arg3, 8);
send_data(arg4, 8);
send_data(crc, 8);
recieve_data();
digitalWrite(CS, HIGH);
这是发送单个位的代码:
digitalWrite(MOSI, HIGH * bit);
digitalWrite(SCLK, HIGH);
delay(CLOCK_TIME / 2.0);
digitalWrite(SCLK, LOW);
delay(CLOCK_TIME / 2.0);