Arduino ESP32 读取SD卡接口选择参考

Posted perseverance52

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Arduino ESP32 读取SD卡接口选择参考相关的知识,希望对你有一定的参考价值。

ESP32 读取SD卡接口选择参考


ESP3232读取SD卡可以通过spi和sdmmc两种方式来读取,不过我们在市面上能买到的都基本上是4线的SPI接口的SD卡模块套件。

  • 卡类型有如下,8-9Pin被引出,但是安装到我们的卡套上就只剩下MOSI,MISO,SCK,CS,GND,VCC

ESP32一共有3组SPI接口

除了下面2两组,另外一组给片上的SPI flash使用。

SD接口

在Arduino libraries库当中SD接口大多采用的SD SPI总线传输模式。
SD实际上有更多的传输模式:

  • SPI总线模式:ESP32有1个以上的SPI总线,可以在初始化时自定义.
  • 1位/ 4位SD总线模式:ESP32提供了另一个名为SD_MMC的库来实现SD总线模式API
  • SD UHS-II模式:ESP32不支持.

ESP32 SPI接口,GPIO引脚映射

1位/ 4位SD总线的GPIO引脚映射不能更改。

  • 简单调用SD_MMC begin()初始4位SD总线模式:
SD_MMC.begin();
  • 可以在SD_MMC begin()方法中选择1位SD总线模式:
SD_MMC.begin("/cdcard", true);
  • 可以在创建SPIClass实例时选择SPI总线(HSPI或VSPI)
SPIClass spi = SPIClass(HSPI);

如你所见,1位/ 4位SD总线引脚与HSPI共享引脚,但SD卡引脚的映射是不一样的。所以如果硬件按照SD总线的引脚图连接,就不能直接使用HSPI本地引脚。GPIO脚可以在SPIClass begin()方法中覆盖.

SPIClass spi = SPIClass(HSPI);
spi.begin(14 /* SCK */, 2 /* MISO */, 15 /* MOSI */, 13 /* SS */);

SD库也可以在SD begin()方法中覆盖SS引脚、SPI总线和总线频率.

SD.begin(13 /* SS */, spi, 80000000);

不同模式下的测试的下载速度


测试程序

/*
 * Connect the SD card to the following pins:
 *
 * SD Card | ESP32
 *    D2       12
 *    D3       13
 *    CMD      15
 *    VSS      GND
 *    VDD      3.3V
 *    CLK      14
 *    VSS      GND
 *    D0       2  (add 1K pull up after flashing)
 *    D1       4
 */
#include "FS.h"
#include "SD.h"
#include "SD_MMC.h"

#define TEST_FILE_SIZE (4 * 1024 * 1024)

void testWriteFile(fs::FS &fs, const char *path, uint8_t *buf, int len)

  unsigned long start_time = millis();
  Serial.printf("Test write %s\\n", path);

  File file = fs.open(path, FILE_WRITE);
  if (!file) 
    Serial.println("Failed to open file for writing");
    return;
  
  int loop = TEST_FILE_SIZE / len;
  while (loop--)
  
    if (!file.write(buf, len)) 
      Serial.println("Write failed");
      return;
    
  
  file.flush();
  file.close();
  unsigned long time_used = millis() - start_time;
  Serial.printf("Write file used: %d ms, %f KB/s\\n", time_used, (float)TEST_FILE_SIZE / time_used);


void testReadFile(fs::FS &fs, const char *path, uint8_t *buf, int len)

  unsigned long start_time = millis();
  Serial.printf("Test read %s\\n", path);

  File file = fs.open(path);
  if (!file) 
    Serial.println("Failed to open file for reading");
    return;
  
  int loop = TEST_FILE_SIZE / len;
  while (loop--)
  
    if (!file.read(buf, len)) 
      Serial.println("Read failed");
      return;
    
  
  file.close();
  unsigned long time_used = millis() - start_time;
  Serial.printf("Read file used: %d ms, %f KB/s\\n", time_used, (float)TEST_FILE_SIZE / time_used);


void testIO(fs::FS &fs)

  /* malloc will not reset all bytes to zero, so it is a random data */
  uint8_t *buf = (uint8_t*)malloc(64 * 1024);

  testWriteFile(fs, "/test_1k.bin", buf, 1024);
  testWriteFile(fs, "/test_2k.bin", buf, 2 * 1024);
  testWriteFile(fs, "/test_4k.bin", buf, 4 * 1024);
  testWriteFile(fs, "/test_8k.bin", buf, 8 * 1024);
  testWriteFile(fs, "/test_16k.bin", buf, 16 * 1024);
  testWriteFile(fs, "/test_32k.bin", buf, 32 * 1024);
  testWriteFile(fs, "/test_64k.bin", buf, 64 * 1024);

  testReadFile(fs, "/test_1k.bin", buf, 1024);
  testReadFile(fs, "/test_2k.bin", buf, 2 * 1024);
  testReadFile(fs, "/test_4k.bin", buf, 4 * 1024);
  testReadFile(fs, "/test_8k.bin", buf, 8 * 1024);
  testReadFile(fs, "/test_16k.bin", buf, 16 * 1024);
  testReadFile(fs, "/test_32k.bin", buf, 32 * 1024);
  testReadFile(fs, "/test_64k.bin", buf, 64 * 1024);


void setup() 
  // put your setup code here, to run once:
  Serial.begin(115200);

  /* test SD_MMC 4-bit Mode */
//  if (!SD_MMC.begin()) 
//    Serial.println("Card Mount Failed");
//    return;
//  
//  testIO(SD_MMC);

  /* test SD_MMC 1-bit Mode */
  if (!SD_MMC.begin("/cdcard", true)) 
    Serial.println("Card Mount Failed");
    return;
  
  testIO(SD_MMC);

  /* test SD SPI Mode at HSPI */
//  SPIClass spi = SPIClass(HSPI);
//  spi.begin(14 /* SCK */, 2 /* MISO */, 15 /* MOSI */, 13 /* SS */);
//  if (!SD.begin(13 /* SS */, spi, 80000000)) 
//    Serial.println("Card Mount Failed");
//    return;
//  
//  testIO(SD);

  /* test SD SPI Mode at VSPI */
//  SPIClass spi = SPIClass(VSPI);
//  spi.begin(18 /* SCK */, 19 /* MISO */, 23 /* MOSI */, 5 /* SS */);
//  if (!SD.begin(5 /* SS */, spi, 80000000)) 
//    Serial.println("Card Mount Failed");
//    return;
//  
//  testIO(SD);


void loop() 

  • SD_MMC 4位模式基准测试

SanDisk 8 GB MicroSD

20:28:17.248 -> Write file used: 17834 ms, 235.185822 KB/s
20:28:17.248 -> Test write /test_4k.bin
20:28:21.122 -> Write file used: 3873 ms, 1082.959961 KB/s
20:28:21.122 -> Test write /test_8k.bin
20:28:23.147 -> Write file used: 2024 ms, 2072.284668 KB/s
20:28:23.147 -> Test write /test_16k.bin
20:28:27.237 -> Write file used: 4097 ms, 1023.750061 KB/s
20:28:27.237 -> Test write /test_32k.bin
20:28:30.088 -> Write file used: 2842 ms, 1475.828247 KB/s
20:28:30.088 -> Test write /test_64k.bin
20:28:31.882 -> Write file used: 1811 ms, 2316.015381 KB/s
20:28:31.882 -> Test read /test_1k.bin
20:28:35.422 -> Read file used: 3520 ms, 1191.563599 KB/s
20:28:35.422 -> Test read /test_2k.bin
20:28:38.813 -> Read file used: 3389 ms, 1237.622925 KB/s
20:28:38.813 -> Test read /test_4k.bin
20:28:42.273 -> Read file used: 3474 ms, 1207.341431 KB/s
20:28:42.273 -> Test read /test_8k.bin
20:28:45.752 -> Read file used: 3487 ms, 1202.840210 KB/s
20:28:45.752 -> Test read /test_16k.bin
20:28:48.988 -> Read file used: 3213 ms, 1305.416748 KB/s
20:28:48.988 -> Test read /test_32k.bin
20:28:52.077 -> Read file used: 3093 ms, 1356.063354 KB/s
20:28:52.077 -> Test read /test_64k.bin
20:28:55.141 -> Read file used: 3080 ms, 1361.786987 KB/s
  • SD_MMC 1位模式基准测试

SanDisk 8 GB MicroSD

20:31:45.194 -> Test write /test_1k.bin
20:31:59.506 -> Write file used: 14325 ms, 292.796082 KB/s
20:31:59.506 -> Test write /test_2k.bin
20:32:17.686 -> Write file used: 18163 ms, 230.925735 KB/s
20:32:17.686 -> Test write /test_4k.bin
20:32:21.291 -> Write file used: 3611 ms, 1161.535278 KB/s
20:32:21.291 -> Test write /test_8k.bin
20:32:23.939 -> Write file used: 2652 ms, 1581.562622 KB/s
20:32:23.939 -> Test write /test_16k.bin
20:32:28.397 -> Write file used: 4448 ms, 942.964050 KB/s
20:32:28.397 -> Test write /test_32k.bin
20:32:31.835 -> Write file used: 3429 ms, 1223.185791 KB/s
20:32:31.835 -> Test write /test_64k.bin
20:32:33.882 -> Write file used: 2058 ms, 2038.048584 KB/s
20:32:33.882 -> Test read /test_1k.bin
20:32:38.031 -> Read file used: 4146 ms, 1011.650757 KB/s
20:32:38.031 -> Test read /test_2k.bin
20:32:42.062 -> Read file used: 4019 ms, 1043.618774 KB/s
20:32:42.062 -> Test read /test_4k.bin
20:32:46.170 -> Read file used: 4106 ms, 1021.506104 KB/s
20:32:46.170 -> Test read /test_8k.bin
20:32:50.288 -> Read file used: 4121 ms, 1017.787903 KB/s
20:32:50.288 -> Test read /test_16k.bin
20:32:54.112 -> Read file used: 3840 ms, 1092.266724 KB/s
20:32:54.112 -> Test read /test_32k.bin
20:32:57.840 -> Read file used: 3739 ms, 1121.771606 KB/s
20:32:57.840 -> Test read /test_64k.bin
20:33:01.568 -> Read file used: 3711 ms, 1130.235474 KB/s

Old 128 MB MicroSD

20:33:27.366 -> Test write /test_1k.bin
20:33:42.386 -> Write file used: 15020 ms, 279.247925 KB/s
20:33:42.386 -> Test write /test_2k.bin
20:33:57.927 -> Write file used: 15515 ms, 270.338654 KB/s
20:33:57.927 -> Test write /test_4k.bin
20:34:13.108 -> Write file used: 15195 ms, 276.031860 KB/s
20:34:13.108 -> Test write /test_8k.bin
20:34:28.162 -> Write file used: 15048 ms, 278.728333 KB/s
20:34:28.162 -> Test write /test_16k.bin
20:34:43.287 -> Write file used: 15142 ms, 276.998016 KB/s
20:34:43.287 -> Test write /test_32k.bin
20:34:58.278 -> Write file used: 14964 ms, 280.292969 KB/s
20:34:58.278 -> Test write /test_64k.bin
20:35:13.370 -> Write file used: 15101 ms, 277.750092 KB/s
20:35:13.370 -> Test read /test_1k.bin
20:35:17.563 -> Read file used: 4197 ms, 999.357666 KB/s
20:35:17.563 -> Test read /test_2k.bin
20:35:21.746 -> Read file used: 4191 ms, 1000.788330 KB/s
20:35:21.746 -> Test read /test_4k.bin
20:35:25.942 -> Read file used: 4181 ms, 1003.182007 KB/s
20:35:25.942 -> Test read /test_8k.bin
20:35:30.101 -> Read file used: 4176 ms, 1004.383118 KB/s
20:35:30.101 -> Test read /test_16k.bin
20:35:34.279 -> Read file used: 4174 ms, 1004.864380 KB/s
20:35:34.279 -> Test read /test_32k.bin
20:35:38.462 -> Read file used: 4173 ms, 1005.105225 KB/s
20:35:38.462 -> Test read /test_64k.bin
20:35:42.612 -> Read file used: 4173 ms, 1005.105225 KB/s
  • 在HSPI总线基准的SD SPI模式

SanDisk 8 GB MicroSD

08:41:19.703 -> Test write /test_1k.bin
08:41:53.458 -> Write file used: 33743 ms, 124.301453 KB/s
08:41:53.458 -> Test write /test_2k.bin
08:42:10.000 -> Write file used: 16540 ms, 253.585495 KB/s
08:42:10.000 -> Test write /test_4k.bin
08:42:17.269 -> Write file used: 7298 ms, 574.719666 KB/s
08:42:17.308 -> Test write /test_8k.bin
08:42:22.640 -> Write file used: 5345 ms, 784.715454 KB/s
08:42:22.640 -> Test write /test_16k.bin
08:42:32.285 -> Write file used: 9662 ms, 434.103088 KB/s
08:42:32.285 -> Test write /test_32k.bin
08:42:36.659 -> Write file used: 4355 ms, 963.100830 KB/s
08:42:36.659 -> Test write /test_64k.bin
08:42:39.594 -> Write file used: 2949 ms, 1422.280151 KB/s
08:42:39.594 -> Test read /test_1k.bin
08:42:44.774 -> Read file usedArduino ESP32 SD卡读写实例

Arduino ESP32 第三方库读取SD卡信息

Arduino ESP32 读取Micro sd卡容量信息示例

Arduino ESP32 使用HSPI和VSPI接口挂载SD卡区别

Arduino ESP32 第三方库读取SD卡信息

Arduino ESP32 Web服务器从microSD卡读取