ESP32-S3-CAM:SD卡开发
·
遇到的问题:
SD卡出初始化总是失败
硬件准备:闪送了一张 闪迪的16G SD卡,和读卡器,用PC格式化为了 FAT32格式和4096 块大小
卡买来就是FAT32,一开始代码没写对,所以就跟着AI提醒做了上述操作,也不知道有没有用。
应该还是代码中初始化代码没写对,AI只给了一句 这样的代码,总是初始化失败。
SD_MMC.begin("/sdcard", false)
板子信息如下,


SD卡槽也看不到具体插的哪个口,后来AI给了一段尝试各种主流型号的口的代码
/*
* GOOUUU ESP32-S3-CAM v1.3 SD 卡文件列表程序
* 功能:初始化 SD 卡并打印根目录所有文件名
*
* SD 卡引脚配置(自动尝试多种组合):
* 组合 A: CLK=39, CMD=38, D0=40 (Freenove 风格)
* 组合 B: CLK=39, CMD=40, D0=47 (Diymore 风格)
* 组合 C: CLK=36, CMD=35, D0=37 (DevKitC 风格)
* 组合 D: CLK=6, CMD=7, D0=4 (早期 S3 风格)
*/
#include <SD_MMC.h>
// 定义要尝试的引脚组合
struct SD_Pins {
const char* name;
int clk;
int cmd;
int d0;
};
SD_Pins pinConfigs[] = {
{"Freenove风格 (39,38,40)", 39, 38, 40},
{"Diymore风格 (39,40,47)", 39, 40, 47},
{"DevKitC风格 (36,35,37)", 36, 35, 37},
{"早期S3风格 (6,7,4)", 6, 7, 4},
{"XIAO风格 (7,9,8)", 7, 9, 8}
};
void setup() {
Serial.begin(115200);
delay(2000);
Serial.println("\n========================================");
Serial.println("GOOUUU ESP32-S3-CAM v1.3 SD 卡测试");
Serial.println("========================================");
// 打印芯片信息
Serial.print("芯片型号: ESP32-S3 (");
Serial.print(ESP.getChipRevision());
Serial.println(")");
Serial.printf("Flash: %d MB\n", ESP.getFlashChipSize() / (1024 * 1024));
Serial.printf("PSRAM: %d MB\n", ESP.getPsramSize() / (1024 * 1024));
Serial.println("----------------------------------------\n");
// 尝试每种引脚配置
bool sdOk = false;
for (int i = 0; i < sizeof(pinConfigs) / sizeof(pinConfigs[0]); i++) {
Serial.printf("[尝试 %d/%d] %s\n", i + 1,
sizeof(pinConfigs) / sizeof(pinConfigs[0]),
pinConfigs[i].name);
Serial.printf(" CLK=%d, CMD=%d, D0=%d\n",
pinConfigs[i].clk, pinConfigs[i].cmd, pinConfigs[i].d0);
if (tryInitSD(pinConfigs[i].clk, pinConfigs[i].cmd, pinConfigs[i].d0)) {
Serial.println(" ✓ SD 卡初始化成功!");
sdOk = true;
break;
} else {
Serial.println(" ✗ 失败");
}
Serial.println();
}
if (!sdOk) {
Serial.println("\n========================================");
Serial.println("所有引脚组合都失败!");
Serial.println("请检查:");
Serial.println("1. SD 卡是否正确插入");
Serial.println("2. SD 卡是否格式化为 FAT32");
Serial.println("3. 开发板是否有物理损坏");
Serial.println("========================================");
return;
}
// 打印 SD 卡信息
printSDInfo();
// 列出根目录文件
Serial.println("\n========================================");
Serial.println("SD 卡根目录文件列表:");
Serial.println("----------------------------------------");
listRootDirectory();
Serial.println("========================================");
}
void loop() {
// 空循环
}
// ==================== 辅助函数 ====================
bool tryInitSD(int clk, int cmd, int d0) {
// 先卸载之前的实例
SD_MMC.end();
delay(100);
// 设置引脚(仅 ESP32-S3 支持)
#ifdef CONFIG_IDF_TARGET_ESP32S3
if (!SD_MMC.setPins(clk, cmd, d0)) {
Serial.println(" setPins() 返回 false");
return false;
}
#endif
// 尝试 1-bit 模式初始化
if (SD_MMC.begin("/sdcard", true)) {
return true;
}
return false;
}
void printSDInfo() {
uint8_t cardType = SD_MMC.cardType();
Serial.println("\n----------------------------------------");
Serial.print("SD 卡类型: ");
switch (cardType) {
case CARD_NONE: Serial.println("未检测到"); break;
case CARD_MMC: Serial.println("MMC"); break;
case CARD_SD: Serial.println("SDSC (标准容量)"); break;
case CARD_SDHC: Serial.println("SDHC (高容量)"); break;
default: Serial.println("未知"); break;
}
if (cardType != CARD_NONE) {
uint64_t cardSize = SD_MMC.cardSize() / (1024 * 1024);
uint64_t totalBytes = SD_MMC.totalBytes() / (1024 * 1024);
uint64_t usedBytes = SD_MMC.usedBytes() / (1024 * 1024);
Serial.printf("SD 卡容量: %llu MB\n", cardSize);
Serial.printf("文件系统总空间: %llu MB\n", totalBytes);
Serial.printf("已用空间: %llu MB\n", usedBytes);
Serial.printf("可用空间: %llu MB\n", totalBytes - usedBytes);
}
Serial.println("----------------------------------------");
}
void listRootDirectory() {
File root = SD_MMC.open("/");
if (!root) {
Serial.println("错误:无法打开根目录");
return;
}
if (!root.isDirectory()) {
Serial.println("错误:根目录不是文件夹");
return;
}
int fileCount = 0;
int dirCount = 0;
File file = root.openNextFile();
if (!file) {
Serial.println("(根目录为空)");
}
while (file) {
if (file.isDirectory()) {
Serial.printf("[DIR] %s/\n", file.name());
dirCount++;
} else {
Serial.printf("[FILE] %-30s %10d bytes\n", file.name(), file.size());
fileCount++;
}
file = root.openNextFile();
}
Serial.println("----------------------------------------");
Serial.printf("总计: %d 个文件, %d 个文件夹\n", fileCount, dirCount);
}
代码说明
自动探测引脚组合
代码会自动尝试 5 种常见的 ESP32-S3-CAM SD 卡引脚配置:
表格
| 组合 | CLK | CMD | D0 | 适用开发板 |
|---|---|---|---|---|
| Freenove | 39 | 38 | 40 | Freenove ESP32-S3-CAM |
| Diymore | 39 | 40 | 47 | Diymore/某些 GOOUUU |
| DevKitC | 36 | 35 | 37 | ESP32-S3-DevKitC |
| 早期 S3 | 6 | 7 | 4 | 早期 ESP32-S3 设计 |
| XIAO | 7 | 9 | 8 | Seeed XIAO ESP32S3 |
运气不错,第一个组合就测出来了
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x1 (POWERON),boot:0x29 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce3818,len:0x508
load:0x403c9700,len:0x4
load:0x403c9704,len:0xad0
load:0x403cc700,len:0x29e4
entry 0x403c9880
========================================
GOOUUU ESP32-S3-CAM v1.3 SD 卡测试
========================================
芯片型号: ESP32-S3 (2)
Flash: 16 MB
PSRAM: 8 MB
----------------------------------------
[尝试 1/5] Freenove风格 (39,38,40)
CLK=39, CMD=38, D0=40
✓ SD 卡初始化成功!
----------------------------------------
SD 卡类型: SDHC (高容量)
SD 卡容量: 15200 MB
文件系统总空间: 15167 MB
已用空间: 2 MB
可用空间: 15165 MB
----------------------------------------
========================================
SD 卡根目录文件列表:
----------------------------------------
[DIR] System Volume Information/
[FILE] audio1.wav 265004 bytes
[FILE] audio2.wav 311084 bytes
[FILE] audio3.wav 291884 bytes
[FILE] audio4.wav 483884 bytes
[FILE] audio5.wav 487724 bytes
[FILE] hello.wav 288044 bytes
----------------------------------------
总计: 6 个文件, 1 个文件夹
========================================
从输出来看,买的这个板子是第一种风格, Freenove风格 (39,38,40),
对应的端口: CLK=39, CMD=38, D0=40
知道了端口就可以简化下代码了,让AI简化了下代码如下:
/*
* GOOUUU ESP32-S3-CAM v1.3 SD 卡文件浏览器
* 引脚: CLK=39, CMD=38, D0=40
*/
#include <SD_MMC.h>
#define SD_CLK 39
#define SD_CMD 38
#define SD_D0 40
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("\n========================================");
Serial.println("ESP32-S3-CAM v1.3 SD 卡文件列表");
Serial.println("========================================");
// 初始化 SD 卡
SD_MMC.setPins(SD_CLK, SD_CMD, SD_D0);
if (!SD_MMC.begin("/sdcard", true)) {
Serial.println("SD 卡初始化失败");
return;
}
// 打印卡信息
uint8_t type = SD_MMC.cardType();
Serial.print("卡类型: ");
if (type == CARD_SD) Serial.println("SD");
else if (type == CARD_SDHC) Serial.println("SDHC");
else if (type == CARD_MMC) Serial.println("MMC");
else Serial.println("未知");
Serial.printf("容量: %llu MB\n", SD_MMC.cardSize() / 1048576);
Serial.printf("已用: %llu MB\n\n", SD_MMC.usedBytes() / 1048576);
// 列出根目录
listDir("/");
}
void loop() {}
void listDir(const char* path) {
File root = SD_MMC.open(path);
if (!root || !root.isDirectory()) return;
File file = root.openNextFile();
while (file) {
if (file.isDirectory()) {
Serial.printf("[DIR] %s/\n", file.name());
} else {
Serial.printf("[FILE] %-25s %8d bytes\n", file.name(), file.size());
}
file = root.openNextFile();
}
}
输出结果如下:
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x1 (POWERON),boot:0x9 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce3818,len:0x508
load:0x403c9700,len:0x4
load:0x403c9704,len:0xad0
load:0x403cc700,len:0x29e4
entry 0x403c9880
========================================
ESP32-S3-CAM v1.3 SD 卡文件列表
========================================
卡类型: SDHC
容量: 15200 MB
已用: 2 MB
[DIR] System Volume Information/
[FILE] audio1.wav 265004 bytes
[FILE] audio2.wav 311084 bytes
[FILE] audio3.wav 291884 bytes
[FILE] audio4.wav 483884 bytes
[FILE] audio5.wav 487724 bytes
[FILE] hello.wav 288044 bytes
总结:在板子上加了什么硬件,都要配置端口号,如果没有对应的端口,就要测出来端口,否则徒劳。
下一篇,要通过外接功放和喇叭,播放SD卡里的音频
更多推荐
所有评论(0)