ESP-IDF 开发
本章节介绍 ESP32-S3-Touch-AMOLED-2.06 的 ESP-IDF 开发环境、工程构建方法,以及产品仓库中 ESP-IDF 示例程序的功能和运行现象。
本章节包含以下部分,请按需阅读:
运行示例前,请确认以下条件已经满足:
- 已准备 ESP32-S3-Touch-AMOLED-2.06 开发板。
- 已使用 USB 数据线连接开发板和电脑。
- 已安装 ESP-IDF 开发环境。
- 推荐使用 ESP-IDF v5.5 或更高版本;
04_Immersive_block的组件清单明确要求 ESP-IDF ≥5.5.0。 - 已安装 VS Code 和 ESP-IDF 扩展,或已经可以在命令行中正常使用
idf.py。 - 已获取产品仓库中的 ESP-IDF 示例程序。
- 首次编译依赖组件管理器的工程时,电脑可以访问 ESP Component Registry。
ESP-IDF 入门教程
初次接触 ESP32 ESP-IDF 开发,想要快速上手?我们为您准备了一套通用的 入门教程。
- 第0节 认识 ESP32
- 第1节 搭建环境
- 第2节 运行实例
- 第3节 创建项目
- 第4节 使用组件
- 第5节 调试程序
- 第6节 FreeRTOS
- 第7节 驱动外设
- 第8节 Wi-Fi 编程
- 第9节 BLE 编程
请注意:该教程使用 ESP32-S3-Zero 作为教学示例,所有硬件代码均基于其引脚布局。在动手实践前,建议您对照手中的开发板引脚图,确认引脚配置无误。
配置 ESP-IDF 开发环境
本产品当前示例使用 LVGL v9.5.0、ESP32-S3 BSP 及 ESP-IDF 新版驱动 API。为保证示例兼容性,推荐使用 ESP-IDF v5.5 或更高版本。
如果切换过 ESP-IDF 版本,请对工程执行 idf.py fullclean,再重新设置目标芯片并构建。
以下内容以 Windows 系统为例,使用 VS Code + ESP-IDF 扩展 的方式进行开发。Mac/Linux 用户请参考 官方说明。
此部分图示以安装 ESP-IDF V5.5.2 为例示范,安装时请选用与您开发板示例匹配的 ESP-IDF 版本。
安装 ESP-IDF 开发环境
-
前往 ESP-IDF Installation Manager 下载 ESP-IDF 安装管理器。这是乐鑫最新推出的跨平台安装工具,下文将演示如何使用其离线安装功能。
在页面中点击 Offline Installer 标签,然后在筛选栏中选择 Windows 操作系统和你需要的 ESP-IDF 版本(图示仅为参考,请以实际为准)。

确认选择无误后,点击下载按钮。浏览器将自动同时下载两个文件:一个是 ESP-IDF 离线整合包(.zst),另一个是 ESP-IDF 安装器(.exe)。

请耐心等待两个文件下载完成。
-
下载完成后,双击运行 ESP-IDF 安装器(eim-gui-windows-x64.exe)。
启动后,可在右上角将界面语言切换为中文。

安装工具会自动检测同一目录下是否存在离线整合包。点击 从存档安装。

接下来,选择安装路径。建议使用默认路径;若需自定义,请确保路径中不包含中文或空格。确认无误后,点击 开始安装。

-
当看到如下界面时,表示 ESP-IDF 已安装成功。

-
建议同时安装驱动程序。点击 完成安装,然后点击 安装驱动程序。

安装 Visual Studio Code 与 ESP-IDF 扩展
-
下载并安装 Visual Studio Code。
-
安装时建议勾选 通过 Code 打开操作添加到 Windows 资源管理器文件上下文菜单,以便快速打开项目文件夹。
-
在 VS Code 中,点击侧边活动栏中的
扩展图标(或使用快捷键 Ctrl + Shift + X)打开 扩展 视图。
-
在搜索框中输入 ESP-IDF,找到 ESP-IDF 扩展并点击安装。

-
当 ESP-IDF 扩展版本 ≥ 2.0 时,扩展会自动检测并识别上述步骤中安装的 ESP-IDF 环境,无需手动配置。
1. 设置目标芯片
本产品主控为 ESP32-S3,首次打开工程后应设置:
idf.py set-target esp32s3
在 VS Code ESP-IDF 扩展中,应选择:
| 设置项 | 选择 |
|---|---|
| Target | esp32s3 |
| Flash method | UART |
| Port | 开发板对应的串口 |
| ESP-IDF version | v5.5 或更高版本 |
2. 组件管理器和网络
示例通过 idf_component.yml 声明部分依赖。首次构建时,ESP-IDF Component Manager 会下载相应组件,并在工程中生成或更新 managed_components 与 dependencies.lock。
当前示例涉及的主要组件包括:
| 组件 | 作用 |
|---|---|
waveshare/esp32_s3_touch_amoled_2_06 | ESP32-S3-Touch-AMOLED-2.06 板级支持包 |
lvgl/lvgl v9.5.0 | 图形界面库 |
espressif/esp_codec_dev | 音频 Codec 支持 |
espressif/usb | USB 组件 |
waveshare/qmi8658 | QMI8658 IMU 驱动 |
espressif/esp-dsp | FFT 和数字信号处理 |
espressif/avi_player | AVI 容器解析和播放 |
espressif/esp_new_jpeg | JPEG 视频帧解码 |
如果首次构建出现组件下载失败,请先检查网络、代理和 ESP Component Registry 的可访问性。不要随意删除示例自带的 idf_component.yml、dependencies.lock 或 sdkconfig.defaults。
示例程序
ESP-IDF 示例位于产品仓库的 examples/esp-idf 目录中。
| 示例程序 | 基础功能 |
|---|---|
| 01_AXP2101 | 通过 I2C 和移植的 XPowersLib 初始化 AXP2101,并处理电源状态 |
| 02_lvgl_demo_v9 | 初始化板级显示和触摸,运行 LVGL v9 Music Demo |
| 03_esp-brookesia | 运行基于 ESP-Brookesia 的手机风格 UI 和 SquareLine Demo 应用 |
| 04_Immersive_block | 使用 QMI8658 加速度数据驱动彩色图形随设备倾斜移动 |
| 05_Spec_Analyzer | 采集音频并执行 FFT,在 AMOLED 屏幕上显示实时频谱 |
| 06_videoplayer | 从 TF 卡循环播放带音频的 AVI 文件 |
本产品的 ESP-IDF 示例主要覆盖以下硬件资源:
| 硬件资源 | 作用 | 相关示例 |
|---|---|---|
| ESP32-S3 主控 | 运行 ESP-IDF、FreeRTOS 和图形/音频任务 | 全部示例 |
| 410×502 AMOLED | 显示 LVGL 界面、动态图形、频谱和视频 | 02~06 |
| FT3168 触摸 | UI 触摸交互 | 02_lvgl_demo_v9、03_esp-brookesia |
| AXP2101 PMU | 电源管理和状态处理 | 01_AXP2101 |
| QMI8658 IMU | 获取加速度数据和倾斜方向 | 04_Immersive_block |
| ES8311 音频 Codec | 音频采集和播放 | 05_Spec_Analyzer、06_videoplayer |
| TF 卡 | 存储 AVI 视频文件 | 06_videoplayer |
如果是第一次使用开发板,建议按以下顺序运行:
01_AXP2101:确认 PMU 和 I2C 通信正常。02_lvgl_demo_v9:确认 AMOLED、触摸和 LVGL 基础功能正常。04_Immersive_block:确认 QMI8658 和动态显示刷新正常。05_Spec_Analyzer:确认音频采集、ESP-DSP 和频谱显示正常。06_videoplayer:确认 TF 卡、JPEG 解码、视频和音频播放正常。03_esp-brookesia:体验组件和资源较多的完整 UI 系统。
1. 目录结构
examples/esp-idf
├── 01_AXP2101
├── 02_lvgl_demo_v9
├── 03_esp-brookesia
├── 04_Immersive_block
├── 05_Spec_Analyzer
└── 06_videoplayer
每个子目录都是一个独立 ESP-IDF 工程。构建前必须进入具体工程目录,不能直接在 examples/esp-idf 目录构建全部示例。
典型工程结构如下:
示例工程
├── CMakeLists.txt
├── main
│ ├── CMakeLists.txt
│ ├── idf_component.yml
│ └── main.c / main.cpp
├── components
│ └── 本地组件
├── dependencies.lock
├── partitions.csv
└── sdkconfig.defaults
各目录或文件的作用:
| 目录或文件 | 说明 |
|---|---|
main/main.c 或 main/main.cpp | 应用入口,阅读示例时应优先查看 |
components | 本地组件,例如 XPowersLib、ESP-Brookesia 或音频扩展 |
idf_component.yml | ESP-IDF Component Manager 依赖声明 |
dependencies.lock | 已解析依赖的锁定版本 |
sdkconfig.defaults | 示例默认配置,包括 PSRAM、LVGL、Flash 等设置 |
partitions.csv | Flash 分区表,图形资源和视频示例需要较大的应用分区 |
CMakeLists.txt | 工程和组件构建配置 |
示例目录中可能同时包含 sdkconfig、sdkconfig.defaults 和 sdkconfig.old。首次使用时建议保留仓库配置;若 ESP-IDF 版本切换后出现异常,可执行 idf.py fullclean,必要时删除当前工程自动生成的 sdkconfig,再由 sdkconfig.defaults 重新生成。
2. 通过 VS Code 运行示例
-
打开 VS Code。
-
选择
File > Open Folder,打开某一个具体示例目录,例如:examples/esp-idf/02_lvgl_demo_v9 -
在 ESP-IDF 状态栏中选择目标芯片
esp32s3。 -
选择
UART下载方式。 -
选择开发板对应的串口。
-
单击 Build 构建工程。
-
单击 Flash 烧录固件。
-
单击 Monitor 查看运行日志。
也可以使用 Build Flash Monitor 一次完成构建、烧录和监视。
如果没有出现串口,可尝试:
- 更换支持数据传输的 USB 线。
- 拔下并重新连接开发板,观察新出现的端口。
- 按住
BOOT后重新连接 USB,再松开BOOT。
3. 通过命令行运行示例
以 02_lvgl_demo_v9 为例:
cd examples/esp-idf/02_lvgl_demo_v9
idf.py set-target esp32s3
idf.py build
idf.py -p PORT flash monitor
将 PORT 替换为实际串口,例如:
idf.py -p COM8 flash monitor
Linux 下可能为:
idf.py -p /dev/ttyACM0 flash monitor
退出串口监视器:
Ctrl + ]
切换 ESP-IDF 版本、目标芯片或示例工程后,可执行:
idf.py fullclean
idf.py set-target esp32s3
idf.py build
idf.py -p PORT flash monitor
4. 示例说明
01_AXP2101
【功能说明】
该示例用于验证 AXP2101 电源管理芯片能否通过 I2C 正常访问,并运行移植的 XPowersLib 电源状态处理逻辑。
主要功能:
- 使用 ESP-IDF 新版 I2C Master API 初始化总线。
- 在 I2C 总线上添加地址为
0x34的 AXP2101 设备。 - 为移植的 XPowersLib 提供寄存器读写接口。
- 调用
pmu_init()初始化 PMU。 - 创建 FreeRTOS 任务,每秒调用一次
pmu_isr_handler()。
【代码入口】
01_AXP2101/main/main.cpp
本地组件:
01_AXP2101/components/XPowersLib
| 函数 | 作用 |
|---|---|
app_main() | 应用入口,完成 I2C、PMU 和任务初始化 |
i2c_init() | 创建 I2C Master Bus,并添加 AXP2101 设备 |
pmu_register_read() | 使用 i2c_master_transmit_receive() 读取 PMU 寄存器 |
pmu_register_write_byte() | 使用 i2c_master_transmit() 写入 PMU 寄存器 |
pmu_hander_task() | 周期性执行 PMU 状态处理 |
pmu_init() | 初始化 AXP2101 |
【正常运行现象】
该示例不使用显示屏。串口日志应出现:
I2C initialized successfully
随后输出 AXP2101 初始化和电源状态相关信息。
如果通信异常,可能出现:
PMU READ FAILED!
PMU WRITE FAILED!
【常见排查】
| 现象 | 可能原因 | 建议处理 |
|---|---|---|
| PMU 读取或写入失败 | I2C 引脚、频率或器件通信异常 | 检查工程配置中的 CONFIG_PMU_I2C_SDA、CONFIG_PMU_I2C_SCL |
| 地址无响应 | I2C 总线初始化失败或器件未供电 | 确认 AXP2101 地址为 0x34,恢复示例默认配置 |
| 编译找不到 XPowersLib | 本地组件目录不完整 | 确认 components/XPowersLib 已完整下载 |
| 没有串口输出 | 端口或监视器选择错误 | 检查端口并重新执行 idf.py -p PORT monitor |
02_lvgl_demo_v9
【功能说明】
该示例使用 Waveshare BSP 初始化 CO5300 AMOLED、FT3168 触摸和 LVGL v9。程序默认运行 LVGL Music Demo,用于验证显示、动画和触摸交互。
当前入口代码默认运行:
lv_demo_music();
代码中还预留了:
// lv_demo_benchmark();
// lv_demo_widgets();
【代码入口】
02_lvgl_demo_v9/main/main.c
主要组件依赖:
waveshare/esp32_s3_touch_amoled_2_06
lvgl/lvgl 9.5.0
espressif/esp_codec_dev ~1.5
espressif/usb ^1.4.1
| 函数或接口 | 作用 |
|---|---|
bsp_display_start() | 初始化显示、触摸、LVGL 和 BSP 资源 |
bsp_display_lock() | 进入 LVGL 临界区 |
lv_demo_music() | 启动 LVGL Music Demo |
bsp_display_unlock() | 退出 LVGL 临界区 |
【正常运行现象】
屏幕显示 LVGL Music Demo。可通过触摸选择界面控件和浏览 Demo 内容。
【切换 Demo】
改为 Benchmark:
// lv_demo_music();
lv_demo_benchmark();
// lv_demo_widgets();
改为 Widgets:
// lv_demo_music();
// lv_demo_benchmark();
lv_demo_widgets();
修改后重新构建和烧录:
idf.py -p PORT flash monitor
【常见排查】
| 现象 | 可能原因 | 建议处理 |
|---|---|---|
| 屏幕不亮 | BSP 初始化、供电或显示配置异常 | 先运行 01_AXP2101,并检查构建日志 |
| 屏幕颜色异常或画面偏移 | 使用了其他型号 BSP 或旧组件缓存 | 确认依赖为 esp32_s3_touch_amoled_2_06,执行 idf.py fullclean |
| 组件下载失败 | 网络或代理异常 | 检查 ESP Component Registry 访问 |
| 触摸无反应 | FT3168 未初始化或当前界面无明显交互 | 切换 Widgets Demo,并查看 BSP 日志 |
| 编译提示 LVGL API 不匹配 | 混用了其他 LVGL 版本 | 保留清单指定的 LVGL v9.5.0 |
03_esp-brookesia
【功能说明】
该示例基于 ESP-Brookesia Phone 框架,展示接近完整产品形态的手机风格 UI 系统。工程包含深色样式、状态栏、导航栏、最近任务界面、应用启动器,以及基于 SquareLine 生成的 Demo 应用。
主要功能:
- 使用自定义 LVGL Port 配置启动 BSP 显示。
- 打开 AMOLED 显示。
- 将 BSP 的显示锁注册到
LvLock。 - 创建并启动
Phone对象。 - 加载并启用深色 Stylesheet。
- 从 App Registry 初始化和安装应用。
- 每秒更新状态栏时钟。
- 周期性更新最近任务界面的内存信息。
【代码入口】
03_esp-brookesia/main/main.cpp
主要本地组件:
03_esp-brookesia/components/brookesia_core
03_esp-brookesia/components/brookesia_app_squareline_demo
SquareLine Demo 中包含时钟、天气、音乐、通话、聊天和闹钟等界面资源。
| 函数或对象 | 作用 |
|---|---|
bsp_display_start_with_config() | 使用指定 LVGL Port 参数启动显示 |
bsp_display_backlight_on() | 打开显示 |
LvLock::registerCallbacks() | 注册 LVGL 线程安全锁 |
Phone | ESP-Brookesia Phone 系统对象 |
phone->begin() | 启动 UI 系统 |
phone->initAppFromRegistry() | 从注册表初始化应用 |
phone->installAppFromRegistry() | 安装注册应用 |
lv_timer_create() | 创建状态栏时间更新定时器 |
【正常运行现象】
屏幕显示手机风格 UI,可通过触摸进入应用、返回、切换页面或查看最近任务。
入口代码使用系统的 time() 和 localtime_r() 更新时间。如果应用没有设置系统时间或完成网络校时,状态栏时钟可能不是当前真实时间。
【常见排查】
| 现象 | 可能原因 | 建议处理 |
|---|---|---|
| 首次编译时间很长 | 本地组件、UI 资源和 C++ 文件较多 | 属于正常现象,等待首次完整构建 |
| 编译提示应用过大 | 分区表未使用示例配置 | 保留示例的 partitions.csv 和 sdkconfig.defaults |
Start display failed | BSP 显示初始化失败 | 先运行 02_lvgl_demo_v9 验证基础显示 |
Begin failed 或 App Registry 失败 | Brookesia 组件或应用资源不完整 | 检查 components/brookesia_core 和 Demo App |
| UI 显示但触摸无响应 | 触摸初始化或 LVGL 锁异常 | 检查串口日志和 LvLock 注册流程 |
04_Immersive_block
【功能说明】
该示例使用 QMI8658 读取加速度数据,并通过 LVGL 创建 15 个随机彩色图形。倾斜开发板时,图形会根据加速度方向移动,同时执行圆角屏幕边界约束和图形碰撞处理。
主要功能:
- 初始化 BSP 显示和 AMOLED。
- 初始化 QMI8658。
- 将加速度计设置为 ±8g、500Hz。
- 采集 200 个样本完成水平校准。
- 应用偏置和死区过滤。
- 创建圆形、方形、三角形和六边形图形。
- 根据加速度更新图形位置。
- 使用
BOOT按键触发重新校准。
【代码入口】
04_Immersive_block/main/main.c
主要组件依赖:
idf >=5.5.0
waveshare/qmi8658
waveshare/esp32_s3_touch_amoled_2_06
lvgl/lvgl 9.5.0
| 函数 | 作用 |
|---|---|
app_main() | 初始化显示、IMU、按键、校准和更新任务 |
perform_level_calibration() | 采集 200 个样本并计算 X/Y 偏置 |
apply_calibration_and_deadzone() | 应用校准偏移和死区 |
generate_random_shapes() | 创建 15 个随机图形 |
shapes_update_task() | 读取加速度并更新图形位置 |
constrain_to_rounded_rect() | 将图形限制在圆角显示区域内 |
handle_shape_collisions() | 处理图形之间的重叠和碰撞 |
init_calibration_button() | 配置 GPIO0/BOOT 按键中断 |
【正常运行现象】
上电后,屏幕底部显示:
Press BOOT to recalibrate
程序先执行水平校准,然后显示多个彩色图形。倾斜开发板时,图形向对应方向移动;按下 BOOT 后重新校准。
串口正常情况下会看到类似日志:
Starting level calibration...
Calibration complete...
Device is now level. Shapes should be stationary.
【使用注意】
- 启动和重新校准时,应将开发板稳定放在水平面上。
- 校准过程约采集 200 个样本;如果数据波动过大,程序会重新校准。
- 水平状态下仍明显漂移时,可再次按
BOOT。
【常见排查】
| 现象 | 可能原因 | 建议处理 |
|---|---|---|
| 图形持续漂移 | 校准时开发板不平或正在晃动 | 放平开发板并按 BOOT 重新校准 |
| 校准不断重试 | 桌面振动或 IMU 数据不稳定 | 保持设备静止,并检查 QMI8658 通信 |
| QMI8658 初始化失败 | I2C 或 BSP 异常 | 检查组件依赖和串口日志 |
按 BOOT 无反应 | GPIO0 中断未注册或被其他功能占用 | 恢复示例默认 GPIO 配置 |
| 编译提示 IDF 版本不满足 | ESP-IDF 低于 v5.5 | 切换到 ESP-IDF v5.5 或更高版本 |
05_Spec_Analyzer
【功能说明】
该示例通过 ES8311/I2S 音频输入采集双声道数据,使用 ESP-DSP 执行 1024 点 FFT,并在 AMOLED 屏幕上绘制 64 条彩色频谱。
主要功能:
- 初始化 BSP 显示和音频 Codec。
- 以 16kHz 采样率读取双声道 16-bit 音频。
- 将左右声道合成为单声道浮点数据。
- 对采样数据应用 Hann 窗。
- 执行 FFT 和位反转。
- 将频域幅值映射为 64 个频谱条。
- 使用 LVGL Canvas 绘制频谱和峰值效果。
【代码入口】
05_Spec_Analyzer/main/main.c
本地音频扩展:
05_Spec_Analyzer/components/bsp_extra
主要组件依赖:
lvgl/lvgl 9.5.0
espressif/esp-dsp
espressif/usb ^1.4.1
关键参数:
| 参数 | 默认值 | 说明 |
|---|---|---|
N_SAMPLES | 1024 | FFT 采样点数 |
SAMPLE_RATE | 16000 | 音频采样率 |
CHANNELS | 2 | 输入声道数 |
STRIPE_COUNT | 64 | 频谱条数量 |
CANVAS_WIDTH | 410 | 频谱画布宽度 |
CANVAS_HEIGHT | 200 | 频谱画布高度 |
DISPLAY_REFRESH_MS | 200 | 频谱数据更新周期 |
| 函数 | 作用 |
|---|---|
app_main() | 初始化显示、Canvas 和 FFT 任务 |
audio_fft_task() | 初始化 Codec、采集音频并执行 FFT |
lv_example_canvas_10() | 创建 410×200 LVGL Canvas |
timer_cb() | 根据频谱数据绘制彩色频谱条 |
bsp_extra_i2s_read() | 读取音频采样 |
【正常运行现象】
屏幕中央显示彩色频谱。环境声音变化时,频谱条的高度和峰值随声音强度和频率分布变化。
串口启动日志中应出现:
Starting Audio Spectrum Analyzer
FFT and window initialized
【常见排查】
| 现象 | 可能原因 | 建议处理 |
|---|---|---|
| 频谱完全不变化 | Codec 初始化失败或没有音频输入 | 检查是否出现 Audio codec init failed |
| 频谱长期接近底部 | 环境声音过小或麦克风链路异常 | 靠近板载麦克风发声进行测试 |
| 提示 I2S 读取错误 | I2S/Codec 配置或音频任务异常 | 检查 components/bsp_extra 和串口日志 |
| 找不到 ESP-DSP | 组件下载未完成 | 检查网络并重新执行 idf.py build |
| Canvas 创建失败或重启 | PSRAM/内存配置不正确 | 使用示例自带 sdkconfig.defaults |
06_videoplayer
【功能说明】
该示例从 TF 卡的 /avi 目录查找 AVI 文件,使用 avi_player 解析视频和音频数据,使用 esp_new_jpeg 解码 MJPEG 视频帧,并通过 ES8311 播放 PCM 音频。
主要功能:
- 初始化 ES8311 音频 Codec,并将音量设置为 80。
- 初始化 BSP 显示和 LVGL。
- 持续尝试挂载 TF 卡。
- 扫描
/sdcard/avi目录内所有.avi文件。 - 创建两个 320×200 RGB565 Canvas 缓冲区。
- 解码 MJPEG 视频帧并交替刷新缓冲区。
- 根据 AVI 音频参数动态设置 I2S 时钟。
- 通过
bsp_extra_i2s_write()播放音频。 - 依次播放所有 AVI 文件并循环。
【代码入口】
06_videoplayer/main/main.c
本地音频扩展:
06_videoplayer/components/bsp_extra
主要组件依赖:
lvgl/lvgl 9.5.0
espressif/avi_player
espressif/esp_new_jpeg
waveshare/esp32_s3_touch_amoled_2_06
| 函数 | 作用 |
|---|---|
app_main() | 初始化音频、显示、TF 卡和播放任务 |
get_avi_file_list() | 枚举 /sdcard/avi 目录中的 AVI 文件 |
init_canvas() | 创建两个 320×200 RGB565 视频缓冲区 |
init_jpeg_decoder() | 初始化 JPEG 解码器 |
video_cb() | 解码 MJPEG 帧并更新 LVGL Canvas |
audio_cb() | 将 AVI 音频数据写入 I2S |
audio_set_clock_callback() | 根据媒体参数设置采样率、位宽和声道 |
avi_play_task() | 顺序播放 AVI 文件并循环 |
【准备 TF 卡】
-
将 TF 卡格式化为常见的 FAT32 文件系统。
-
在 TF 卡根目录创建
avi文件夹。 -
将 AVI 文件放入:
/avi├── video1.avi└── video2.avi -
断电后插入 TF 卡,再启动示例。
示例的视频画布为 320×200,推荐将视频转换为 MJPEG + PCM:
ffmpeg -i input.mp4 -vf scale=320:200 -c:v mjpeg -r 30 -q:v 2 -c:a pcm_s16le -ar 44100 -ac 2 output.avi
将生成的 output.avi 放入 TF 卡的 /avi 目录。
【正常运行现象】
启动后,屏幕先显示 TF 卡挂载状态:
Mounting SD card...
Attempt: 1
挂载成功并找到 AVI 文件后,状态文字消失,视频以 320×200 大小显示在屏幕中央,同时播放音频。多个 AVI 文件会依次播放,列表结束后从头循环。
串口日志类似:
Found 2 AVI files in directory /sdcard/avi
Playing: /sdcard/avi/video1.avi (1/2)
AVI playback finished
【使用注意】
- 示例只扫描
/avi目录,不扫描 TF 卡根目录或子目录。 - 文件扩展名不区分大小写,但必须为
.avi。 - 视频帧解码输出不得超过 320×200 RGB565 缓冲区。
- 代码会一直重试挂载 TF 卡;未插卡时会持续显示不断增加的 Attempt 次数。
- 如果
/avi目录不存在或没有 AVI 文件,屏幕会显示错误并停止继续播放。
【常见排查】
| 现象 | 可能原因 | 建议处理 |
|---|---|---|
一直显示 Mounting SD card | TF 卡未插好、格式不兼容或硬件连接异常 | 断电后重新插卡,优先使用 FAT32 |
显示 No AVI files found in /sdcard/avi | 目录名或文件格式错误 | 确认文件位于 TF 卡根目录下的 avi 文件夹 |
| JPEG header 或 decode 失败 | AVI 视频编码不是受支持的 MJPEG | 使用推荐的 FFmpeg 命令重新转换 |
Output buffer too small | 视频分辨率超过 320×200 | 将视频缩放为 320×200 |
| 有画面但没有声音 | AVI 无 PCM 音轨或 Codec/I2S 初始化异常 | 使用 PCM S16LE 音频重新转换,并查看串口日志 |
| 视频播放卡顿 | 帧率、码率、TF 卡速度或解码负载过高 | 降低帧率、JPEG 质量或视频尺寸 |
| 提示内存分配失败 | PSRAM 或工程配置不匹配 | 使用示例自带 sdkconfig.defaults |
常见问题汇总
| 问题 | 建议 |
|---|---|
| 构建提示 ESP-IDF 版本不满足 | 使用 ESP-IDF v5.5 或更高版本 |
| 找不到 LVGL v9.5.0 API | 删除错误的本地 LVGL 覆盖,并让组件管理器按清单下载 |
| 首次构建下载组件失败 | 检查网络、代理和 ESP Component Registry |
| 编译或链接仍使用旧配置 | 执行 idf.py fullclean 后重新构建 |
| 图形示例启动时重启 | 保留 sdkconfig.defaults、分区表和 PSRAM 配置 |
| 画面偏移、触摸坐标或外设异常 | 确认使用 waveshare/esp32_s3_touch_amoled_2_06 BSP,不要混用 2.16 或其他尺寸产品组件 |
| 烧录时找不到设备 | 更换 USB 数据线、确认端口,必要时按住 BOOT 后重新连接 |
| Monitor 无日志 | 检查端口占用,并重新执行 idf.py -p PORT monitor |