背景知识:
ESP32有两种使用SD卡的方法,一种是使用SPI接口访问SD卡,另一种是使用SDMMC接口访问SD卡 。
Arduino core for the ESP32中SPI方式占用4个IO口,SDMMC方式占用6个IO口,一般来说SDMMC方式速度要比SPI方式快。
1. SDMMC方式
ESP32虽然有两组SDMMC接口,但Arduino core for the ESP32中只用到了其中一组,IO口连接为:DAT2 - IO12
、DAT3 - IO13
、CMD - IO15
、CLK - IO14
、DAT0 - IO2
、DAT1 - IO4
;
bool begin(const char * mountpoint="/sdcard", bool mode1bit=false)
挂载存储卡,输入参数分别为挂载点、是否使用一线模式;
void end()
取消挂载;
sdcard_type_t cardType() 返回存储卡类型,0、1、2、3、4,分别如下:
CARD_NONE 未连接存储卡;
CARD_MMC mmc卡;
CARD_SD sd卡,最大2G;
CARD_SDHC sdhc卡,最大32G;
CARD_UNKNOWN 未知存储卡;
uint64_t cardSize() 返回存储卡大小字节数;
uint64_t totalBytes() 返回文件系统总字节数;
uint64_t usedBytes() 返回文件系统已用字节数;
2. SPI方式
bool begin(uint8_t ssPin=SS, SPIClass &spi=SPI, uint32_t frequency=4000000, const char * mountpoint="/sd", uint8_t max_files=5)
挂载存储卡,输入参数分别为SS引脚号、SPI对象、时钟频率、挂载点、文件最大同时打开数;
默认IO口连接为:CS - IO5、DI - IO23、SCLK - IO18、DO - IO19;
void end()
取消挂载;
sdcard_type_t cardType() 返回存储卡类型,0、1、2、3、4,分别如下:
CARD_NONE 未连接存储卡;
CARD_MMC mmc卡;
CARD_SD sd卡,最大2G;
CARD_SDHC sdhc卡,最大32G;
CARD_UNKNOWN 未知存储卡;
uint64_t cardSize() 返回存储卡大小字节数;
uint64_t totalBytes() 返回文件系统总字节数;
uint64_t usedBytes(); 返回文件系统已用字节数
3. 我的实验
我手头的ESP32_CAM板子的原理图
右图可知,我的SD卡接到了ESP32的GPIO12 13 14 15 2 4 这6个脚上,根据前述,这符合SDMMC方式的IO连接。所以,我在软件上需要使用SDMMC方式来驱动SD卡。
新建arduino项目文件,复制黏贴如下代码,即可以SDMMC方式驱动SD卡
//引用相关库 //#include "FS.h" #include "SD_MMC.h" // 接口连接如下: // SD卡 - ESP32 // ------------ // DAT2 - IO12 // DAT3 - IO13 // CMD - IO15 // CLK - IO14 // DAT0 - IO2 // DAT1 - IO4 void setup() { Serial.begin(115200); Serial.println(); //挂载文件系统 if (!SD_MMC.begin()) { Serial.println("存储卡挂载失败"); return; } uint8_t cardType = SD_MMC.cardType(); if (cardType == CARD_NONE) { Serial.println("未连接存储卡"); return; } else 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("挂载了未知存储卡"); } //打开/建立 并写入数据 File file = SD_MMC.open("/test.txt", FILE_WRITE); if (file) { Serial.println("打开/建立 根目录下 test.txt 文件!"); } char data[] = "hello world\r\n"; file.write((uint8_t *)data, strlen(data)); file.close(); //重命名文件 if (SD_MMC.rename("/test.txt", "/retest.txt")) { Serial.println("test.txt 重命名为 retest.txt !"); } //读取文件数据 file = SD_MMC.open("/retest.txt", FILE_READ); if (file) { Serial.print("文件内容是:"); while (file.available()) { Serial.print((char)file.read()); } } //打印存储卡信息 Serial.printf("存储卡总大小是: %lluMB \n", SD_MMC.cardSize() / (1024 * 1024)); // "/ (1024 * 1024)"可以换成">> 20" Serial.printf("文件系统总大小是: %lluB \n", SD_MMC.totalBytes()); Serial.printf("文件系统已用大小是: %lluB \n", SD_MMC.usedBytes()); } void loop() { }
4. 实验效果
5.补充,如果不追求读写SD卡的速率,那么可以SPI方式来进行SD卡的读写,那么这样就可以省下ESP32宝贵的2个GPIO作其他用途。
其实,这些例程在我们安装好Arduino的ESP32支持包以后,我们电脑本地已经有了,参考下面的路径可以找到这些例程。
.