0

我正在尝试初始化 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);
4

0 回答 0