проблема инициализации micro SD на ESP32-DevKitC V4

Ivan_X

✩✩✩✩✩✩✩
11 Ноя 2025
9
0
Здравствуйте! У меня не получается запустить micro SD на ESP32, я уже пробовал 2 карты, но так и не запустилось. Карт-ридер подключен к базовым пинам VSPI, Использовал код с примера библиотеки SD (SDtest), даже немного дорабатывал его, ставил в ArduinoIDE ESP32 Dev module и ESP32_WROOM_DA, ничего не поменялось) Использовал абсолютно новый карт-ридер, популярный на aliexpress, синий, такой длинный, не знаю как объяснить:) Кто возможно сталкивался с подобным, подскажите пожалуйста возможные решения проблемы. Вот код который я использовал:

C++:
/*
 * pin 1 - not used          |  Micro SD card     |
 * pin 2 - CS (SS)           |                   /
 * pin 3 - DI (MOSI)         |                  |__
 * pin 4 - VDD (3.3V)        |                    |
 * pin 5 - SCK (SCLK)        | 8 7 6 5 4 3 2 1   /
 * pin 6 - VSS (GND)         | ▄ ▄ ▄ ▄ ▄ ▄ ▄ ▄  /
 * pin 7 - DO (MISO)         | ▀ ▀ █ ▀ █ ▀ ▀ ▀ |
 * pin 8 - not used          |_________________|
 *                             ║ ║ ║ ║ ║ ║ ║ ║
 *                     ╔═══════╝ ║ ║ ║ ║ ║ ║ ╚═════════╗
 *                     ║         ║ ║ ║ ║ ║ ╚══════╗    ║
 *                     ║   ╔═════╝ ║ ║ ║ ╚═════╗  ║    ║
 * Connections for     ║   ║   ╔═══╩═║═║═══╗   ║  ║    ║
 * full-sized          ║   ║   ║   ╔═╝ ║   ║   ║  ║    ║
 * SD card             ║   ║   ║   ║   ║   ║   ║  ║    ║
 * Pin name         |  -  DO  VSS SCK VDD VSS DI CS    -  |
 * SD pin number    |  8   7   6   5   4   3   2   1   9 /
 *                  |                                  █/
 *                  |__▍___▊___█___█___█___█___█___█___/
 *
 * Note:  The SPI pins can be manually configured by using `SPI.begin(sck, miso, mosi, cs).`
 *        Alternatively, you can change the CS pin and use the other default settings by using `SD.begin(cs)`.
 *
 * +--------------+---------+-------+----------+----------+----------+----------+----------+
 * | SPI Pin Name | ESP8266 | ESP32 | ESP32‑S2 | ESP32‑S3 | ESP32‑C3 | ESP32‑C6 | ESP32‑H2 |
 * +==============+=========+=======+==========+==========+==========+==========+==========+
 * | CS (SS)      | GPIO15  | GPIO5 | GPIO34   | GPIO10   | GPIO7    | GPIO18   | GPIO0    |
 * +--------------+---------+-------+----------+----------+----------+----------+----------+
 * | DI (MOSI)    | GPIO13  | GPIO23| GPIO35   | GPIO11   | GPIO6    | GPIO19   | GPIO25   |
 * +--------------+---------+-------+----------+----------+----------+----------+----------+
 * | DO (MISO)    | GPIO12  | GPIO19| GPIO37   | GPIO13   | GPIO5    | GPIO20   | GPIO11   |
 * +--------------+---------+-------+----------+----------+----------+----------+----------+
 * | SCK (SCLK)   | GPIO14  | GPIO18| GPIO36   | GPIO12   | GPIO4    | GPIO21   | GPIO10   |
 * +--------------+---------+-------+----------+----------+----------+----------+----------+
 *
 * For more info see file README.md in this library or on URL:
 * https://github.com/espressif/arduino-esp32/tree/master/libraries/SD
 */

#include "FS.h"
#include "SD.h"
#include "SPI.h"

SPIClass vspi = SPIClass(VSPI);

#define REASSIGN_PINS
int sck = 18;
int miso = 19;
int mosi = 23;
int cs = 5;

void listDir(fs::FS &fs, const char *dirname, uint8_t levels) {
  Serial.printf("Listing directory: %s\n", dirname);

  File root = fs.open(dirname);
  if (!root) {
    Serial.println("Failed to open directory");
    return;
  }
  if (!root.isDirectory()) {
    Serial.println("Not a directory");
    return;
  }

  File file = root.openNextFile();
  while (file) {
    if (file.isDirectory()) {
      Serial.print("  DIR : ");
      Serial.println(file.name());
      if (levels) {
        listDir(fs, file.path(), levels - 1);
      }
    } else {
      Serial.print("  FILE: ");
      Serial.print(file.name());
      Serial.print("  SIZE: ");
      Serial.println(file.size());
    }
    file = root.openNextFile();
  }
}

void createDir(fs::FS &fs, const char *path) {
  Serial.printf("Creating Dir: %s\n", path);
  if (fs.mkdir(path)) {
    Serial.println("Dir created");
  } else {
    Serial.println("mkdir failed");
  }
}

void removeDir(fs::FS &fs, const char *path) {
  Serial.printf("Removing Dir: %s\n", path);
  if (fs.rmdir(path)) {
    Serial.println("Dir removed");
  } else {
    Serial.println("rmdir failed");
  }
}

void readFile(fs::FS &fs, const char *path) {
  Serial.printf("Reading file: %s\n", path);

  File file = fs.open(path);
  if (!file) {
    Serial.println("Failed to open file for reading");
    return;
  }

  Serial.print("Read from file: ");
  while (file.available()) {
    Serial.write(file.read());
  }
  file.close();
}

void writeFile(fs::FS &fs, const char *path, const char *message) {
  Serial.printf("Writing file: %s\n", path);

  File file = fs.open(path, FILE_WRITE);
  if (!file) {
    Serial.println("Failed to open file for writing");
    return;
  }
  if (file.print(message)) {
    Serial.println("File written");
  } else {
    Serial.println("Write failed");
  }
  file.close();
}

void appendFile(fs::FS &fs, const char *path, const char *message) {
  Serial.printf("Appending to file: %s\n", path);

  File file = fs.open(path, FILE_APPEND);
  if (!file) {
    Serial.println("Failed to open file for appending");
    return;
  }
  if (file.print(message)) {
    Serial.println("Message appended");
  } else {
    Serial.println("Append failed");
  }
  file.close();
}

void renameFile(fs::FS &fs, const char *path1, const char *path2) {
  Serial.printf("Renaming file %s to %s\n", path1, path2);
  if (fs.rename(path1, path2)) {
    Serial.println("File renamed");
  } else {
    Serial.println("Rename failed");
  }
}

void deleteFile(fs::FS &fs, const char *path) {
  Serial.printf("Deleting file: %s\n", path);
  if (fs.remove(path)) {
    Serial.println("File deleted");
  } else {
    Serial.println("Delete failed");
  }
}

void testFileIO(fs::FS &fs, const char *path) {
  File file = fs.open(path);
  static uint8_t buf[512];
  size_t len = 0;
  uint32_t start = millis();
  uint32_t end = start;
  if (file) {
    len = file.size();
    size_t flen = len;
    start = millis();
    while (len) {
      size_t toRead = len;
      if (toRead > 512) {
        toRead = 512;
      }
      file.read(buf, toRead);
      len -= toRead;
    }
    end = millis() - start;
    Serial.printf("%u bytes read for %lu ms\n", flen, end);
    file.close();
  } else {
    Serial.println("Failed to open file for reading");
  }

  file = fs.open(path, FILE_WRITE);
  if (!file) {
    Serial.println("Failed to open file for writing");
    return;
  }

  size_t i;
  start = millis();
  for (i = 0; i < 2048; i++) {
    file.write(buf, 512);
  }
  end = millis() - start;
  Serial.printf("%u bytes written for %lu ms\n", 2048 * 512, end);
  file.close();
}

void setup() {
  Serial.begin(115200);
  pinMode(cs, OUTPUT);
  vspi.begin(sck, miso, mosi, cs);
#ifdef REASSIGN_PINS
  vspi.begin(sck, miso, mosi, cs);
  if (!SD.begin(cs, vspi, 20000000)) {
#else
  if (!SD.begin()) {
#endif
    Serial.println("Card Mount Failed");
    return;
  }
  uint8_t cardType = SD.cardType();

  if (cardType == CARD_NONE) {
    Serial.println("No SD card attached");
    return;
  }

  Serial.print("SD Card Type: ");
  if (cardType == CARD_MMC) {
    Serial.println("MMC");
  } else if (cardType == CARD_SD) {
    Serial.println("SDSC");
  } else if (cardType == CARD_SDHC) {
    Serial.println("SDHC");
  } else {
    Serial.println("UNKNOWN");
  }

  uint64_t cardSize = SD.cardSize() / (1024 * 1024);
  Serial.printf("SD Card Size: %lluMB\n", cardSize);

  listDir(SD, "/", 0);
  createDir(SD, "/mydir");
  listDir(SD, "/", 0);
  removeDir(SD, "/mydir");
  listDir(SD, "/", 2);
  writeFile(SD, "/hello.txt", "Hello ");
  appendFile(SD, "/hello.txt", "World!\n");
  readFile(SD, "/hello.txt");
  deleteFile(SD, "/foo.txt");
  renameFile(SD, "/hello.txt", "/foo.txt");
  readFile(SD, "/foo.txt");
  testFileIO(SD, "/test.txt");
  Serial.printf("Total space: %lluMB\n", SD.totalBytes() / (1024 * 1024));
  Serial.printf("Used space: %lluMB\n", SD.usedBytes() / (1024 * 1024));
}

void loop() {}
 

SlavaZagaynov

★✩✩✩✩✩✩
27 Ноя 2019
212
41
www.youtube.com
попробуй не SD, a SD_MMC

p.s. это точно работатет
для подключения 3 проводов достаточно
SD_MMC.setPins(clk, cmd, d0)
 
Изменено:
  • Лойс +1
Реакции: Ivan_X

Ivan_X

✩✩✩✩✩✩✩
11 Ноя 2025
9
0

@SlavaZagaynov, А MMC это разве не другой тип карт? Им вроде нужен другой карт-ридер с другими пинами? У меня на карт-ридере нет пинов CMD, D#, выведен только стандартный SPI: (MISO, MOSI, SCK, CS)
 

SlavaZagaynov

★✩✩✩✩✩✩
27 Ноя 2019
212
41
www.youtube.com
@Ivan_X, я давно с этим разбирался, подробностей не помню. Там что-то типа такого... Были карты SD со своим протоколом передачи данных и всё сбыло хорошо, а потом стали видео снимать, потребовалась высокая скорость и SD такая и говорит, "я не успеваю, хоть убейте меня".
Ну инженеры репу почесали и убили её, сделали новый програмный протокол в ставом физическом формате карт.
А на картах не пишут что за карта, только иногда на устройствых, что поддерживаются карты только до 16 ГБ, но и это не факт что заработает.
Реально старый формат это карты на 1 ГБ, если у тебя такая из прошлого века завалялать, то она заработает.

см. Схема подключения для режима 1-bit
 
  • Лойс +1
Реакции: Ivan_X

SlavaZagaynov

★✩✩✩✩✩✩
27 Ноя 2019
212
41
www.youtube.com
я использкю такие пины
GPIO_39: : SD_MMC CMD (mosi)
GPIO_40: : SD_MMC CLK (clk)
GPIO_41: : SD_MMC D0 (miso)

код:
            int clk = 40;
            int cmd = 39;
            int d0  = 41;          
           
            Serialprintln("запуск SD_MMC "+String(clk)+"/"+String(cmd)+"/"+String(d0));
           
    if(! SD_MMC.setPins(clk, cmd, d0)){
        Serialprintln("! ERR SD_MMC Pin change failed!");
    }          

  if (!SD_MMC.begin("/sdcard", true)) {    Serialprintln("! ERR SD_MMC Card Mount Failed");  }
  uint8_t cardType = SD_MMC.cardType();

  if (cardType == CARD_NONE) {    Serialprintln("! ERR SD_MMC No SD_MMC card attached");  }

  Serialprintln("SD_MMC Card Type: ");
  if (cardType == CARD_MMC) {    Serialprintln("MMC");
  } else if (cardType == CARD_SD) {    Serialprintln("SDSC");
  } else if (cardType == CARD_SDHC) {    Serialprintln("SDHC");
  } else {    Serialprintln("UNKNOWN");
  }

  uint64_t cardSize = SD_MMC.cardSize() / (1024 * 1024);
  Serial.printf("SD_MMC Card Size: %lluMB\n", cardSize);

  Serial.printf("Total space: %lluMB\n", SD_MMC.totalBytes() / (1024 * 1024));
  Serial.printf("Used space: %lluMB\n", SD_MMC.usedBytes() / (1024 * 1024));
 
  • Лойс +1
Реакции: Ivan_X

kapitanrtv

✩✩✩✩✩✩✩
29 Июн 2021
1
0
У меня так
CS - GPIO2
SCK - GPI04
MOSI - GPI06
MISO - GPI05
Хотя долго не запускалась, оказалось что работает только от 5в 3,3 ей мало....