赞
踩
开发板:NodeMCU32s(v1.3)
SD卡读写模块:SDIO/SPI 二合一
SD卡:闪迪 32GB(TF卡,实际29.7GB)/ Kingston 32G (TF卡,实际29.1GB)
开发框架:Arduino
Esp32 可以通过 SDMMC 和 SPI 两种方式读取SD/TF卡数据。
- SDMMC 分为 1 位 SD 总线模式和 4 位 SD 总线模式
- Esp32 上有 4 组 SPI 外设,其中,控制器 SPI2 和 SPI3 分别使用带前缀 HSPI 和 VSPI 的信号总线。
注意:
setup
函数后恢复供电(因此需要在 setup
函数中加入适当延时),否则 Esp32 会无限重启。 【4 位 SD 总线模式、HSPI 会发生】下载程序到 Esp32 时未断开 SD 卡供电,出现报错信息:
Timed out waiting for packet header
硬件连线方式:
-----------------------------------------------
| NodeMCU32s | SD Card |
| --------------------------------------------
| GPIO12 | D02 |
| GPIO4 | D01 |
| GPIO15 | CMD(MOSI) |
| GPIO2 | D00(MISO) |
| GPIO14 | CLK(SCK) |
| GPIO13 | D03(SS) |
| GND | GND |
| VCC(3.3v) | VCC |
-----------------------------------------------
#include "FS.h" #include "SD.h" #include "SD_MMC.h" void WriteFile(fs::FS &fs, const char *path, uint8_t *buf, int len) { //unsigned long start_time = millis(); Serial.printf("write [%s]...\n", path); File file = fs.open(path, FILE_WRITE); if (!file) { Serial.println("Failed to open file for writing"); return; } if (!file.write(buf, len)) { Serial.println("Write failed"); return; } file.flush(); file.close(); Serial.printf("Write [%s] Complete", path); } void ReadFile(fs::FS &fs, const char *path, uint8_t *buf, int len) { Serial.printf("read [%s]...\n", path); File file = fs.open(path); if (!file) { Serial.println("Failed to open file for reading"); return; } if (!file.read(buf, len)) { Serial.println("Read failed"); return; } file.close(); Serial.printf("Read [%s] Complete: %s", path, buf); } void testIO(fs::FS &fs) { char buf[] = "hello world"; WriteFile(fs, "/test.txt", (uint8_t *)buf, strlen(buf)); ReadFile(fs, "/test.txt", (uint8_t *)buf, strlen(buf)); } void setup() { // put your setup code here, to run once: Serial.begin(115200); Serial.println("请插入内存卡"); delay(8000); /* SD_MMC 4-bit Mode */ if (!SD_MMC.begin()) { Serial.println("Card Mount Failed"); return; } testIO(SD_MMC); SD_MMC.end(); // 取消SD挂载 void loop() { }
硬件连线方式:
-----------------------------------------------
| NodeMCU32s | SD Card |
| --------------------------------------------
| - | D02 |
| - | D01 |
| GPIO15 | CMD(MOSI) |
| GPIO2 | D00(MISO) |
| GPIO14 | CLK(SCK) |
| - | D03(SS) |
| GND | GND |
| VCC(3.3v) | VCC |
-----------------------------------------------
#include "FS.h" #include "SD.h" #include "SD_MMC.h" void WriteFile(fs::FS &fs, const char *path, uint8_t *buf, int len) { //unsigned long start_time = millis(); Serial.printf("write [%s]...\n", path); File file = fs.open(path, FILE_WRITE); if (!file) { Serial.println("Failed to open file for writing"); return; } if (!file.write(buf, len)) { Serial.println("Write failed"); return; } file.flush(); file.close(); Serial.printf("Write [%s] Complete", path); } void ReadFile(fs::FS &fs, const char *path, uint8_t *buf, int len) { Serial.printf("read [%s]...\n", path); File file = fs.open(path); if (!file) { Serial.println("Failed to open file for reading"); return; } if (!file.read(buf, len)) { Serial.println("Read failed"); return; } file.close(); Serial.printf("Read [%s] Complete: %s", path, buf); } void testIO(fs::FS &fs) { char buf[] = "hello world"; WriteFile(fs, "/test.txt", (uint8_t *)buf, strlen(buf)); ReadFile(fs, "/test.txt", (uint8_t *)buf, strlen(buf)); } void setup() { // put your setup code here, to run once: Serial.begin(115200); Serial.println("请插入内存卡"); delay(8000); /* SD_MMC 1-bit Mode */ if (!SD_MMC.begin("/cdcard", true)) { Serial.println("Card Mount Failed"); return; } testIO(SD_MMC); SD_MMC.end(); // 取消SD挂载 void loop() { }
硬件连线方式:
-----------------------------------------------
| NodeMCU32s | SD Card |
| --------------------------------------------
| - | D02 |
| - | D01 |
| GPIO13 | CMD(MOSI) |
| GPIO12 | D00(MISO) |
| GPIO14 | CLK(SCK) |
| GPIO15 | D03(SS) |
| GND | GND |
| VCC(3.3v) | VCC |
-----------------------------------------------
#include "FS.h" #include "SD.h" #include "SD_MMC.h" void WriteFile(fs::FS &fs, const char *path, uint8_t *buf, int len) { //unsigned long start_time = millis(); Serial.printf("write [%s]...\n", path); File file = fs.open(path, FILE_WRITE); if (!file) { Serial.println("Failed to open file for writing"); return; } if (!file.write(buf, len)) { Serial.println("Write failed"); return; } file.flush(); file.close(); Serial.printf("Write [%s] Complete", path); } void ReadFile(fs::FS &fs, const char *path, uint8_t *buf, int len) { Serial.printf("read [%s]...\n", path); File file = fs.open(path); if (!file) { Serial.println("Failed to open file for reading"); return; } if (!file.read(buf, len)) { Serial.println("Read failed"); return; } file.close(); Serial.printf("Read [%s] Complete: %s", path, buf); } void testIO(fs::FS &fs) { char buf[] = "hello world"; WriteFile(fs, "/test.txt", (uint8_t *)buf, strlen(buf)); ReadFile(fs, "/test.txt", (uint8_t *)buf, strlen(buf)); } void setup() { // put your setup code here, to run once: Serial.begin(115200); Serial.println("请插入内存卡"); delay(8000); /* SD SPI Mode at HSPI */ SPIClass spi = SPIClass(HSPI); spi.begin(14 /* SCK */, 12 /* MISO */, 13 /* MOSI */, 15 /* SS */); if (!SD.begin(15 /* SS */, spi, 80000000)) { Serial.println("Card Mount Failed"); return; } testIO(SD); SD_MMC.end(); // 取消SD挂载 void loop() { }
采用 32GB 闪迪 TF卡出现以下问题:
换成 32GB Kingston TF 卡正常。如果还不正常可以尝试换容量小一点的 TF 卡。
硬件连线方式:
-----------------------------------------------
| NodeMCU32s | SD Card |
| --------------------------------------------
| - | D02 |
| - | D01 |
| GPIO23 | CMD(MOSI) |
| GPIO19 | D00(MISO) |
| GPIO18 | CLK(SCK) |
| GPIO5 | D03(SS) |
| GND | GND |
| VCC(3.3v) | VCC |
-----------------------------------------------
#include "FS.h" #include "SD.h" #include "SD_MMC.h" void WriteFile(fs::FS &fs, const char *path, uint8_t *buf, int len) { //unsigned long start_time = millis(); Serial.printf("write [%s]...\n", path); File file = fs.open(path, FILE_WRITE); if (!file) { Serial.println("Failed to open file for writing"); return; } if (!file.write(buf, len)) { Serial.println("Write failed"); return; } file.flush(); file.close(); Serial.printf("Write [%s] Complete", path); } void ReadFile(fs::FS &fs, const char *path, uint8_t *buf, int len) { Serial.printf("read [%s]...\n", path); File file = fs.open(path); if (!file) { Serial.println("Failed to open file for reading"); return; } if (!file.read(buf, len)) { Serial.println("Read failed"); return; } file.close(); Serial.printf("Read [%s] Complete: %s", path, buf); } void testIO(fs::FS &fs) { char buf[] = "hello world"; WriteFile(fs, "/test.txt", (uint8_t *)buf, strlen(buf)); ReadFile(fs, "/test.txt", (uint8_t *)buf, strlen(buf)); } void setup() { // put your setup code here, to run once: Serial.begin(115200); Serial.println("请插入内存卡"); delay(8000); /* SD SPI Mode at VSPI */ SPIClass spi = SPIClass(HSPI); 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); SD_MMC.end(); // 取消SD挂载 void loop() { }
采用 32GB 闪迪 TF卡出现 VSPI 同样问题,换成 32GB Kingston TF 卡正常。
参考:
[1]: Arduino ESP32 读取SD卡接口选择参考
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。