先移植sd卡代码并挂载

//sd卡相关头文件
#include "driver/sdmmc_host.h"
#include "sdmmc_cmd.h"
#include "esp_vfs_fat.h"

#define BSP_SD_CLK          (47)
#define BSP_SD_CMD          (48)
#define BSP_SD_D0           (21)

static const char *TAG = "main";

#define MOUNT_POINT              "/sdcard"//定义SD卡挂载点
#define EXAMPLE_MAX_CHAR_SIZE    64

esp_err_t sd_card_mount(void)// 初始化并挂载SD卡
{
    esp_err_t ret;

    esp_vfs_fat_sdmmc_mount_config_t mount_config = {
        .format_if_mount_failed = true,   // 如果挂载不成功是否需要格式化SD卡
        .max_files = 5, // 允许打开的最大文件数
        .allocation_unit_size = 16 * 1024  // 分配单元大小
    };
    
    sdmmc_card_t *card;
    const char mount_point[] = MOUNT_POINT;
    ESP_LOGI(TAG, "Initializing SD card");
    ESP_LOGI(TAG, "Using SDMMC peripheral");

    sdmmc_host_t host = SDMMC_HOST_DEFAULT(); // SDMMC主机接口配置
    sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT(); // SDMMC插槽配置
    slot_config.width = 1;  // 设置为1线SD模式
    slot_config.clk = BSP_SD_CLK; 
    slot_config.cmd = BSP_SD_CMD;
    slot_config.d0 = BSP_SD_D0;
    slot_config.flags |= SDMMC_SLOT_FLAG_INTERNAL_PULLUP; // 打开内部上拉电阻

    ESP_LOGI(TAG, "Mounting filesystem");
    ret = esp_vfs_fat_sdmmc_mount(mount_point, &host, &slot_config, &mount_config, &card); // 挂载SD卡

    if (ret != ESP_OK) {  // 如果没有挂载成功
        if (ret == ESP_FAIL) { // 如果挂载失败
            ESP_LOGE(TAG, "Failed to mount filesystem. ");
        } else { // 如果是其它错误 打印错误名称
            ESP_LOGE(TAG, "Failed to initialize the card (%s). ", esp_err_to_name(ret));
        }
        return ret;
    }
    ESP_LOGI(TAG, "Filesystem mounted"); // 提示挂载成功
    
    return ESP_OK;
}

然后app.main中写

ESP_ERROR_CHECK(sd_card_mount());
    ESP_LOGI(TAG, "SD卡挂载成功");

然后cmake文件中添加头文件搜索路径和fatfs(文件系统)、vfs(虚拟文件系统)、sdmmc(SD/MMC 卡驱动)这三个组件

# 3. 注册 ESP-IDF 组件
idf_component_register(
    SRCS ${srcs}
    INCLUDE_DIRS ${include_dirs}
    INCLUDE_DIRS "."
    REQUIRES fatfs vfs sdmmc
    REQUIRES lvgl esp_lvgl_port driver
)

INCLUDE_DIRS "."

REQUIRES fatfs vfs sdmmc

就这两行

配置LVGL的文件系统posix驱动

打开menuconfig->3rd Party Libraries->File system on top of posix API

  • 83 是字母 S 的 ASCII,这样在代码里才能用 "S:/xxx" 访问 SD 卡(例如 lv_img_set_src(img, "S:/img.bin"))【这里的s是盘符】
  • working directory是挂载sd卡的位置【这里填sdcard就是实际sd卡的挂载点,相当于盘符 83、路径 /sdcard → S:/heiji5.bin 实际打开的是 /sdcard/heiji5.bin】

然后app_main里添加

#if LV_USE_FS_POSIX
    lv_fs_posix_init();   // 注册 LVGL 的 POSIX 驱动,之后可用 "S:/xxx" 访问 SD 卡(对应 /sdcard)
    ESP_LOGI(TAG, "LVGL 文件系统驱动注册成功 (S: -> /sdcard)");
#endif

这里文件系统使用posix而不是fatFS主要是因为后者还要配置ff.h

然后LVGL文件系统就挂载成功了,可以直接读取bin文件

图片转换:

初始图片分辨率比较高,要转换为LVGL对应尺寸的分辨率,然后再转换为bin文件

使用Image Converter — LVGL进行图片转换(我也是试了很多次才得出这个选项,其他的都是花屏)

转换好的bin文件放到sd卡即可读取

修改guiguider生成的代码:

选择外部存储,存储的文件夹叫sdcard

这里生成的很多与s盘符相关的图片操作就是读取sd卡内的图片,把png改为bin[因为bin文件不需要解码,更轻小方便]

然后sd卡内创建sdcard文件夹,放入用到的bin文件即可

读取优化:

开启文件系统缓存

开启LVGL图片缓存

【如果不开启这两个,每次刷新/重绘时,LVGL 都会从 SD 卡重新读图,SD 又比内部 Flash 慢很多,所以会明显卡顿】


修改LVGL缓冲显示高度:

#define BSP_LCD_DRAW_BUF_HEIGHT    (60)//绘制缓冲区高度

受限于SD卡的单线读取,优化到这里已经很快了,但是还是有一点卡顿,如果再想优化,可以改为内部flash存储

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐