ESP32学习笔记(43)——SD卡使用(SDMMC方式)

发布者:HappyHearted最新更新时间:2025-02-26 来源: jianshu关键字:ESP32  SD卡 手机看文章 扫描二维码
随时随地手机看文章

一、简介

SD 卡(Secure Digital Memory Card) 在我们生活中已经非常普遍了,控制器对 SD 卡进行
读写通信操作一般有两种通信接口可选,一种是 SPI 接口,另外一种就是 SDIO 接口。
SDIO 全称是安全数字输入/输出接口,多媒体卡(MMC)、SD 卡、SD I/O 卡都有 SDIO 接口。
MMC 卡可以说是 SD 卡的前身,现阶段已经用得很少。

二、API说明

以下 SDMMC 接口位于 driver/include/driver/sdmmc_host.h。

2.1 SDMMC_HOST_DEFAULT

SDMMC_HOST_DEFAULT()
SDMMC 外设的默认sdmmc_host_t结构初始值设定项。
使用 SDMMC 外设,启用 4 位模式,最大频率设置为 20MHz

2.2 SDMMC_SLOT_CONFIG_DEFAULT

SDMMC_SLOT_CONFIG_DEFAULT()
定义 SDMMC 主机插槽默认配置的宏
以下 FAT 文件系统接口位于 fatfs/vfs/esp_vfs_fat.h。

2.3 esp_vfs_fat_sdmmc_mount

2.4 esp_vfs_fat_sdcard_unmount



以下 SDMMC 接口位于 sdmmc/include/sdmmc_cmd.h。


2.5 sdmmc_card_print_info

三、编程流程

  1. 使用“一体式” esp_vfs_fat_sdmmc_mount()函数进行初始化:

    • 初始化SDMMC外设;

    • 检测并初始化连接到SD/MMC插槽1的卡(HS2_CMD、HS2_CLK、HS2_D0、HS2_D1、HS2_D2、HS2_D3线);

    • 使用FATFS库安装FAT文件系统(如果无法安装文件系统,则使用格式化卡);

    • 在VFS中注册FAT文件系统,以使用C标准库和POSIX函数。

  2. 打印有关SD卡的信息,例如名称、类型、容量和支持的最大频率。

  3. 使用fopen()创建一个文件,并使用fprintf()写入该文件。

  4. 重命名该文件。重命名之前,请使用stat()函数检查目标文件是否已存在,并使用unlink()函数将其删除。

  5. 打开重命名的文件进行读取,读回该行,并将其打印到终端。

四、硬件连接

我使用的是 ESP32-LyraT V4.3 开发板


以下功能可通过功能 DIP 开关进行选择:


  • 在 1-wire 模式下启用 MicroSD 卡

拨码开关位置
1OFF
2OFF
3OFF
4OFF
5OFF
6OFF
7OFF①
8N/A

①:通过拨动 DIP SW 7 ON可以启用AUX 输入检测。请注意,系统上电时不应插入AUX 输入信号引脚。否则 ESP32 可能无法正常启动。

在这种模式下:

  • JTAG功能不可用

  • Vol- touch 按钮可用于 API

  • 在 4-wire 模式下启用 MicroSD 卡 (例程默认使用的模式)

拨码开关位置
1ON
2ON
3OFF
4OFF
5OFF
6OFF
7OFF
8N/A

在这种模式下:

  • JTAG功能不可用

  • Vol- touch 按钮可用于 API

  • 来自 API 的AUX 输入检测不可用

五、示例代码

根据 examplesstoragesd_card 中的例程修改

默认是4-wire 模式,1-wire 模式修改slot_config.width = 1;


/* SD card and FAT filesystem example.

   This example code is in the Public Domain (or CC0 licensed, at your option.)


   Unless required by applicable law or agreed to in writing, this

   software is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES OR

   CONDITIONS OF ANY KIND, either express or implied.

*/#include #include #include #include #include 'esp_err.h'#include 'esp_log.h'#include 'esp_vfs_fat.h'#include 'driver/sdspi_host.h'#include 'driver/spi_common.h'#include 'sdmmc_cmd.h'#include 'sdkconfig.h'#include 'driver/sdmmc_host.h'static const char *TAG = 'example';#define MOUNT_POINT '/sdcard'// This example can use SDMMC and SPI peripherals to communicate with SD card.// By default, SDMMC peripheral is used.void app_main(void){

    esp_err_t ret;

    // Options for mounting the filesystem.

    // If format_if_mount_failed is set to true, SD card will be partitioned and

    // formatted in case when mounting fails.

    esp_vfs_fat_sdmmc_mount_config_t mount_config = {

        .format_if_mount_failed = true,

        .max_files = 5,

        .allocation_unit_size = 16 * 1024

    };

    sdmmc_card_t* card;

    const char mount_point[] = MOUNT_POINT;

    ESP_LOGI(TAG, 'Initializing SD card');


    // Use settings defined above to initialize SD card and mount FAT filesystem.

    // Note: esp_vfs_fat_sdmmc/sdspi_mount is all-in-one convenience functions.

    // Please check its source code and implement error recovery when developing

    // production applications.

    ESP_LOGI(TAG, 'Using SDMMC peripheral');

    sdmmc_host_t host = SDMMC_HOST_DEFAULT();


    // This initializes the slot without card detect (CD) and write protect (WP) signals.

    // Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals.

    sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();


    // To use 1-line SD mode, uncomment the following line:

    // slot_config.width = 1;


    // GPIOs 15, 2, 4, 12, 13 should have external 10k pull-ups.

    // Internal pull-ups are not sufficient. However, enabling internal pull-ups

    // does make a difference some boards, so we do that here.

    gpio_set_pull_mode(15, GPIO_PULLUP_ONLY);   // CMD, needed in 4- and 1- line modes

    gpio_set_pull_mode(2, GPIO_PULLUP_ONLY);    // D0, needed in 4- and 1-line modes

    gpio_set_pull_mode(4, GPIO_PULLUP_ONLY);    // D1, needed in 4-line mode only

    gpio_set_pull_mode(12, GPIO_PULLUP_ONLY);   // D2, needed in 4-line mode only

    gpio_set_pull_mode(13, GPIO_PULLUP_ONLY);   // D3, needed in 4- and 1-line modes


    // 初始化 SD卡

    ret = esp_vfs_fat_sdmmc_mount(mount_point, &host, &slot_config, &mount_config, &card);


    // 初始化不成功

    if (ret != ESP_OK) {

        if (ret == ESP_FAIL) {

            ESP_LOGE(TAG, 'Failed to mount filesystem. '

                'If you want the card to be formatted, set the EXAMPLE_FORMAT_IF_MOUNT_FAILED menuconfig option.');

        } else {

            ESP_LOGE(TAG, 'Failed to initialize the card (%s). '

                'Make sure SD card lines have pull-up resistors in place.', esp_err_to_name(ret));

        }

        return;

    }


    // Card has been initialized, print its properties

    sdmmc_card_print_info(stdout, card);


    // Use POSIX and C standard library functions to work with files.

    // First create a file.

    ESP_LOGI(TAG, 'Opening file');

    FILE* f = fopen(MOUNT_POINT'/hello.txt', 'w');

    if (f == NULL) {

        ESP_LOGE(TAG, 'Failed to open file for writing');

        return;

    }

    fprintf(f, 'Hello %s!n', card->cid.name);

    fclose(f);

    ESP_LOGI(TAG, 'File written');


    // Check if destination file exists before renaming

    struct stat st;

    if (stat(MOUNT_POINT'/foo.txt', &st) == 0) {

        // Delete it if it exists

        unlink(MOUNT_POINT'/foo.txt');

    }


    // Rename original file

    ESP_LOGI(TAG, 'Renaming file');

    if (rename(MOUNT_POINT'/hello.txt', MOUNT_POINT'/foo.txt') != 0) {

        ESP_LOGE(TAG, 'Rename failed');

        return;

    }


    // Open renamed file for reading

    ESP_LOGI(TAG, 'Reading file');

    f = fopen(MOUNT_POINT'/foo.txt', 'r');

    if (f == NULL) {

        ESP_LOGE(TAG, 'Failed to open file for reading');

        return;

    }

    char line[64];

    fgets(line, sizeof(line), f);

    fclose(f);

    // strip newline

    char* pos = strchr(line, 'n');

    if (pos) {

        *pos = '';

    }

    ESP_LOGI(TAG, 'Read from file: '%s'', line);


    // All done, unmount partition and disable SDMMC or SPI peripheral

    esp_vfs_fat_sdcard_unmount(mount_point, card);

    ESP_LOGI(TAG, 'Card unmounted');}


查看打印:


关键字:ESP32  SD卡 引用地址:ESP32学习笔记(43)——SD卡使用(SDMMC方式)

上一篇:ESP32学习笔记(44)——SD卡使用(SPI方式)
下一篇:ESP32学习笔记(42)——硬件定时器接口使用

推荐阅读最新更新时间:2026-03-16 01:43

ESP32/8266固件备份方法
Esptool是一个开源且官方的命令行工具,主要用于对乐鑫(Espressif)的ESP系列芯片进行固件读写和调试。它通过串口(UART)与ESP设备的Bootloader(引导加载程序)通信,按照特定协议发送指令和数据,以执行各种底层操作。由于esptool是一个Python脚本,因此需要先安装Python环境。安装完成后,用户即可在命令行中使用esptool.py命令。 与其他工具的关系: IDE:当您在 Arduino IDE 中点击“上传”按钮时,IDE 实际上是在后台调用了 esptool(或其变种 arduino-esp32 中的工具)来完成固件烧录。您无需手动操作。 PlatformIO:PlatformIO 同样
[嵌入式]
<font color='red'>ESP32</font>/8266固件备份方法
STM32与ESP32核心应用场景解析及PCB设计实践(深度探讨)
在PCB设计中选择微控制器时,STM32与ESP32的核心差异在于应用定位:STM32以实时控制和外设扩展性见长,适合工业与复杂嵌入式系统;ESP32则凭借集成无线通信与低功耗特性,主导物联网和消费电子领域。以下从六大维度展开深度分析: 一、核心架构与性能对比 STM32:实时控制的基石 ARM Cortex-M系列内核(M0+/M3/M4/M7),主频覆盖16MHz至480MHz(如STM32H7),单核计算能力突出。 硬件级实时响应:纳秒级中断延迟,适用于电机控制、无人机飞控等强实时场景。 丰富外设接口:支持多路高精度ADC(16位)、CAN总线、USB OTG、以太网等工业级外设。 ESP32:物联网的高效
[单片机]
STM32与<font color='red'>ESP32</font>核心应用场景解析及PCB设计实践(深度探讨)
串口、并口、USB、UART及RS232/RS485接口与ESP32、STM32的应用解析
在嵌入式系统和电子设备开发中,理解各种通信接口和主流微控制器的区别至关重要。本文将清晰梳理几组关键概念的区别,助您在项目选型时做出明智决策。 一、 串行接口 vs. 并行接口 核心区别:数据传输方式 串行接口: 数据位在一根(单工)或一对(双工) 信号线上依次、一位接一位地传输。例如:UART、I2C、SPI、USB、RS232、RS485、以太网等。 优点: 线路简单、成本低、抗干扰能力强(尤其远距离)、连接器引脚少、布线方便。 缺点: 相对并行接口,速度较慢(同一时钟周期只传1位)。 典型应用: 远距离通信、设备间点对点或总线通信、对速度要求不极端高的场景。 并行接口: 数据位通过多根(通常8位、16位、32位等)
[单片机]
串口、并口、USB、UART及RS232/RS485接口与<font color='red'>ESP32</font>、STM32的应用解析
ESP32省电模式连接WIFI笔记
基于ESP-IDF4.1版本 main.c文件如下: #include string.h #include freertos/FreeRTOS.h #include freertos/task.h #include freertos/event_groups.h #include esp_system.h #include esp_wifi.h #include esp_event.h #include esp_log.h #include nvs_flash.h #include esp_pm.h #include lwip/err.h #include lwip/sys.h //值在sd
[单片机]
ESP32智能配网笔记
基于ESP-IDF4.1 #include string.h #include stdlib.h #include freertos/FreeRTOS.h #include freertos/task.h #include freertos/event_groups.h #include esp_wifi.h #include esp_wpa2.h #include esp_event.h #include esp_log.h #include esp_system.h #include nvs_flash.h #include esp_netif.h #include esp_smartconfig.
[单片机]
ESP32存储blog笔记
基于ESP-IDF4.1 1 #include stdio.h 2 #include freertos/FreeRTOS.h 3 #include freertos/task.h 4 #include esp_system.h 5 #include nvs_flash.h 6 #include nvs.h 7 #include driver/gpio.h 8 9 #define STORAGE_NAMESPACE storage 10 11 12 //保存设备重启数 13 esp_err_t save_restart_counter(void) 14 { 15 nvs_hand
[单片机]
ESP32使用SPIFFS文件系统笔记
基于ESP-IDF4.1 1 #include stdio.h 2 #include string.h 3 #include sys/unistd.h 4 #include sys/stat.h 5 #include esp_err.h 6 #include esp_log.h 7 #include esp_spiffs.h 8 9 static const char *TAG = example ; 10 11 void app_main(void) 12 { 13 ESP_LOGI(TAG, Initializing SPIFFS ); 14 15 esp_vfs_spiffs_conf_t c
[单片机]
ESP32的Flash加密知识
一、Flash 加密功能用于加密与 ESP32-S2 搭载使用的 SPI Flash 中的内容。启用 Flash 加密功能后,物理读取 SPI Flash 便无法恢复大部分 Flash 内容。通过明文数据烧录 ESP32-S2 可应用加密功能,(若已启用加密功能)引导加载程序会在首次启动时对数据进行加密。 启用 Flash 加密后,系统将默认加密下列类型的 Flash 数据: 引导加载程序 分区表 所有 “app” 类型的分区 其他类型的 Flash 数据将视情况进行加密: 安全启动引导加载程序摘要(如果已启用安全启动) 分区表中标有“加密”标记的分区 二、开发模式:可使用 ESP32-S2 内部生成的密钥或外部主
[单片机]
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved