Aeduino下ESP32-S3-N16R8使用Micro SD卡模块

ESP32-S3-N16R8是一款基于ESP32-S3芯片的开发板或模组,其名称中的“N16R8”通常表示该设备具有16MB的Flash存储和8MB的PSRAM(伪静态随机存取存储器)。

存储配置:

  • Flash:16MB,用于存储程序代码、数据等。
  • PSRAM:8MB,作为外部RAM,扩展了ESP32-S3的内存容量,使得设备能够处理更复杂的应用和更大的数据集。

对我来说,相较于ESP32 WROOM,S3的针脚更加丰富再就是RAM和FLASH容量更大,可以满足更加复杂的开发环境,尤其是对于多线程的使用时。

  • ESP32-S3:搭载Xtensa® 32位LX7双核处理器,同样支持高达240 MHz的时钟频率。与ESP32 WROOM相比,ESP32-S3在处理器架构上有所升级,加入了用于加速神经网络计算和信号处理等工作的向量指令,从而在性能上有了可观的提升。此外,ESP32-S3还内置了512 KB SRAM(TCM),相较于ESP32 WROOM的520 KB SRAM,虽然容量略小,但结合其向量指令集和优化的处理器架构,整体性能依然非常出色。
  • 在存储方面,ESP32-S3支持更大容量的高速Octal SPI flash和片外RAM(如8 MB PSRAM),为用户提供了更大的存储空间。同时,ESP32-S3也配备了丰富的外设接口,包括45个可编程GPIO管脚、多个SPI、I2C、UART等接口,以及用于高速数据传输的SDIO和RMT接口。这些接口使得ESP32-S3能够轻松连接各种复杂的外设设备,满足多样化的应用需求。

使用Micro SD卡模块

        ESP32在Arduino下使用SD卡模块是有很多开发比较完善的库的,我使用的是ESP32自带的SD库,在安装ESP32的包时是自带的,使用Arduino IDE可以在实例中看到,其中有两个示例都可以测试,基本上可以满足大多数的需求:

        以下是我使用的SD卡模块:

        

硬件准备完成之后,稍微麻烦一点的就是接线了,SD模块与ESP32使用的是SPI通信,相较于ESP32 WROOM默认使用的VSPI:

ESP32-S3使用的是HSPI,不注意很容易搞错,接线如下,具体可以去看S3的数据手册:

然后就可以使用烧录例程进行测试了:

/*
 * Connect the SD card to the following pins:
 *
 * SD Card | ESP32
 *    D2       -
 *    D3       SS
 *    CMD      MOSI
 *    VSS      GND
 *    VDD      3.3V
 *    CLK      SCK
 *    VSS      GND
 *    D0       MISO
 *    D1       -
 */
#include "FS.h"
#include "SD.h"
#include "SPI.h"

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 %u 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 %u ms\n", 2048 * 512, end);
    file.close();
}

void setup(){
    Serial.begin(115200);
    if(!SD.begin()){
        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(){

}

注意:

选择板子如下:

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ESP32-S3-WROOM-1(N16R2)是一款带有PSRAM的ESP32-S3开发板。为了正确配置该开发板,你需要进行以下步骤: 1. 设置开发板编译参数,将`MICROPY_HW_BOARD_NAME`从ESP32-S3-DevKitC-1-N8R2修改为ESP32-S3-DevKitC-1-N16R8。 2. 修改`mpconfigboard.mk`文件中的`USB_PRODUCT`,将其从ESP32-S3-DevKitC-1-N8R2修改为ESP32-S3-DevKitC-1-N16R8。 3. 修改`CIRCUITPY_ESP_FLASH_MODE`,将其从dio修改为qio,以支持Flash的QIO模式。 4. 修改`CIRCUITPY_ESP_FLASH_SIZE`,将其从8MB修改为16MB,以适应16MB的Flash大小。 5. 编辑`sdkconfig`文件,将`CONFIG_SPIRAM_MODE_QUAD`修改为`CONFIG_SPIRAM_MODE_OCT`,以支持PSRAM的Octal模式。 6. 修改`CONFIG_SPIRAM_SIZE`,将其从2097152修改为8388608,以适应8MB的PSRAM大小。 此外,你还可以参考官方文档和规格书来了解更多关于ESP32-S3-WROOM-1(N16R2)的详细信息和配置方式。在VS Code中配置Flash和PSRAM时,需要将Flash SPI mode设置为QIO,速度设置为80MHz,而PSRAM的SPI mode需要参考文档使用Octal Mode,速度需要与Flash相同,也是80MHz。在VsCode PlatformIO中的配置示例如下: ``` \[env:esp32s3box\] platform = espressif32 board = esp32-s3-devkitc-1 framework = arduino upload_port = COM9 upload_speed = 115200 ``` 这样,你就可以正确配置ESP32-S3-WROOM-1(N16R2)开发板了。 #### 引用[.reference_title] - *1* [ESP32-S3-WROOM-1-N16R8 编译 CircuitPython 固件](https://blog.csdn.net/weixin_47702151/article/details/126801942)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [ESP32-S3-WROOM-1-N16R8 配置PSRAM](https://blog.csdn.net/chenjk10/article/details/128215276)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [ESP32-S3 N8R2 烧录调试记录](https://blog.csdn.net/feiduoxuetang/article/details/130747222)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值