开始前适用开发板:ESP32-S3 Korvo · 开发框架:ESP-IDF
适用开发板:Korvo S3 · 工程
03.development.lvgl_esp_adapter· targetesp32s3
前置:SPI 屏触摸
内容:esp_lvgl_adapter+ BSP 跑lv_demo_benchmark
学习时长:约 15 分钟 · 难度:★★☆☆☆
学习目标
完成本节后,你将能够:
- 理解
esp_lvgl_adapter在 LVGL 移植中的角色与优势 - 区分「手写 LVGL port」与「BSP + adapter」两种集成方式
- 阅读 benchmark 结果并评估显示性能
- 在此基础上搭建自己的 LVGL 应用
1. 这个例子在干嘛
本例程用 esp_lvgl_adapter + ksdiy_korvo_bsp 的「标准化」方式运行 LVGL,并执行官方 lv_demo_benchmark 来验证整体图形管线性能。
与 spi_lcd_touch 例程的对比:
| 对比项 | spi_lcd_touch | 本例(lvgl_esp_adapter) |
|---|---|---|
| LVGL 移植方式 | 手写 flush 回调、tick 定时器 | 通过 adapter 组件自动完成 |
| 显示驱动 | 手动初始化 SPI + ST7789 | BSP 一键初始化 |
| 触摸驱动 | 手动 I2C + CST816S | BSP 集成 |
| 适合场景 | 学习 LVGL 移植原理 | 产品开发推荐方式 |
教学类比:
spi_lcd_touch相当于从零手搓发动机,lvgl_esp_adapter相当于直接用整车——产品工程应该用后者。
2. 软件架构
┌─────────────────────────────────────────────┐
│ 应用代码 │
│ lv_demo_benchmark() │
├─────────────────────────────────────────────┤
│ LVGL 9 核心 │
├──────────────┬──────────────────────────────┤
│ Display Port │ Input Device Port │
│ (flush) │ (touch read) │
├──────────────┴──────────────────────────────┤
│ esp_lvgl_adapter │ ← 自动桥接 LVGL 与驱动
├──────────────┬──────────────────────────────┤
│ ST7789 SPI │ CST816S I2C │
│ 240×280 │ 触摸控制器 │
├──────────────┴──────────────────────────────┤
│ ksdiy_korvo_bsp │ ← 板级支持包
└─────────────────────────────────────────────┘
esp_lvgl_adapter 做了什么?
- 自动创建 LVGL display 驱动并注册 flush 回调
- 自动创建 esp_timer 提供 LVGL tick
- 自动创建独立 FreeRTOS 任务运行
lv_timer_handler() - 支持多种屏幕接口(SPI、I2C、RGB、MIPI)的统一适配
3. 编译烧录
cd Korvo_Firmware\03.development.lvgl_esp_adapter
idf.py set-target esp32s3
idf.py build flash monitor
4. 运行现象
| 阶段 | 屏幕表现 | 串口输出 |
|---|---|---|
| 启动 | 短暂白屏或黑屏 | 初始化日志 |
| Benchmark 运行中 | 循环切换多个测试场景(矩形、文字、图片、渐变等) | 各场景 FPS 数据 |
| 完成 | 显示总分或停在最后一个场景 | 汇总结果 |
怎么看 Benchmark 结果?
- Weighted FPS:综合帧率,越高越好
- 单场景 FPS 低于 15 → 该类型渲染有瓶颈
- Korvo 240×280 SPI 屏参考值:20~40 FPS(取决于 SPI 时钟和缓冲策略)
5. 关键文件与代码解析
| 文件 | 作用 | 重点关注 |
|---|---|---|
main/app_main.c | 入口:调用 BSP 初始化 + 启动 benchmark | 仅几行代码即完成 |
components/ksdiy_korvo_bsp | 板级支持包 | 封装了 SPI、触摸、背光等所有硬件初始化 |
managed_components/esp_lvgl_adapter | LVGL 适配层 | 自动下载,无需手动添加 |
典型 app_main 结构:
app_main()
→ bsp_display_start() // BSP 初始化屏幕 + 触摸 + LVGL
→ bsp_display_lock(0) // 获取 LVGL 互斥锁
→ lv_demo_benchmark() // 启动 benchmark
→ bsp_display_unlock() // 释放锁
关键点:所有 LVGL API 调用都必须在
bsp_display_lock/unlock之间——这是多线程安全的要求。
6. 性能优化指南
如果 benchmark 结果不理想,可以从以下方面优化:
| 优化项 | 方法 | 效果 |
|---|---|---|
| SPI 时钟 | 提高 LCD_SPI_CLK_HZ(最大 80 MHz) | 直接提升刷屏带宽 |
| 双缓冲 | 配置两个 flush buffer | 减少 CPU 等待 SPI 传输的空闲时间 |
| PSRAM | 缓冲区放 PSRAM,释放 SRAM | 支持更大缓冲区 |
| 局部刷新 | 若 ST7789 支持,开启 set_px_map_partial | 仅更新变化区域 |
7. 常见问题与排查
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 白屏/无画面 | SPI 接线、TCA9554 背光未开 | 检查 BSP 引脚定义;先跑 spi_lcd_touch 验证 |
| FPS 偏低 | PSRAM 未启用或时钟低 | menuconfig → PSRAM → QPI 80MHz |
| 触摸无效/偏移 | 屏幕旋转与触摸坐标不匹配 | BSP 中 rotation 设置需与 adapter 一致 |
| 编译缺组件 | esp_lvgl_adapter 下载失败 | 检查网络,idf.py reconfigure |
8. 动手改造建议
- 替换 Demo:将
lv_demo_benchmark()换成lv_demo_widgets(),体验完整的 LVGL 控件库 - 自定义界面:在 benchmark 之后创建一个自己的 LVGL 页面(按钮 + 标签)
- 对比测试:分别测试 SPI 40MHz 和 80MHz 的 benchmark 差异,记录数据
- 触摸交互:添加触摸回调,在按下时改变屏幕颜色
9. 知识延伸
- 为什么推荐 adapter 而不是手写 port? 手写移植容易遗漏线程安全、tick 精度、DMA 对齐等细节,adapter 已经处理好了
- LVGL 8 vs LVGL 9:本套例程已升级到 LVGL 9,API 有较大变化(
lv_disp_drv_t→lv_display_t等),不要照搬 LVGL 8 的教程 - BSP 的价值:换板只需换 BSP 组件,应用代码可以 零修改 移植
10. 下一步
| 方向 | 推荐例程 |
|---|---|
| MP3 播放器(LVGL UI) | MP3 |
| 完整 LVGL V9 学习 | 03.development.lvgl_v9 |
| 通用 LVGL 教程 | LVGL V9 教程 |
酷世DIY · Kevincoooool