ESP32-S3 TR2S LVGL 代码说明
文档导航 — 本文为总览;各子系统详见:
下载代码
1. 硬件平台
| 组件 | 规格 |
|---|---|
| 主控 | ESP32-S3 (N16R8), 双核 Xtensa LX7, 240 MHz |
| 显示屏 | TR2S QSPI LCD, 800×480, RGB565 |
| 触摸屏 | 电容屏, 默认 GT911 (I2C), 可选 TR230S (复用 LCD SPI/QSPI) |
| LVGL 版本 | v8.3.11, 全屏双缓冲 (PSRAM ~1.46 MB) |
| ESP-IDF 版本 | v5.1.2 |
TR2S 硬件支持 SPI / QSPI / 8080-8B / 8080-16B,当前仅实现 SPI 和 QSPI 驱动。
2. 硬件资源分配
| 信号 | GPIO | QSPI 模式 | SPI 模式 |
|---|---|---|---|
| D0 / MOSI | GPIO 4 | QSPI 数据线 0 | SPI MOSI |
| D1 / MISO | GPIO 5 | QSPI 数据线 1 | SPI MISO |
| D2 | GPIO 6 | QSPI 数据线 2 + WP | — |
| D3 | GPIO 7 | QSPI 数据线 3 + HD | — |
| CLK | GPIO 16 | 时钟线 | 时钟线 |
| CS | GPIO 15 | 片选 | 片选 |
| DC | GPIO 19 | — (无需 DC) | 命令/数据选择 |
| RST | GPIO 18 | 复位 (低有效) | 复位 (低有效) |
| WAIT | GPIO 46 | 忙等待 (低=忙) | 忙等待 (低=忙) |
| CTP SDA | GPIO 39 | 触摸 I2C 数据 | 触摸 I2C 数据 |
| CTP SCL | GPIO 38 | 触摸 I2C 时钟 | 触摸 I2C 时钟 |
| CTP INT | GPIO 45 | 触摸中断 | 触摸中断 |
| CTP RST | GPIO 48 | 触摸复位 | 触摸复位 |
总线配置:
| 总线 | 控制器 | 模式 | 频率 | 用途 |
|---|---|---|---|---|
| QSPI/SPI | SPI3_HOST | Quad / Standard, 半双工 | 80 MHz | LCD 显示 + 可选的触摸通信 |
| I2C | I2C_NUM_1 | 主机 | 400 kHz | 触摸屏 (GT911 等, 默认) |
当
TR230S_EN使能时,TP 驱动通过qspilcd.c导出的lcd_ctp_write_cmd()/lcd_ctp_read_cmd()复用 LCD 的 SPI 总线,不再初始化 I2C。
3. 代码结构
esp32_lvgl/
├── CMakeLists.txt # 项目根 CMake (设置 EXTRA_COMPONENT_DIRS)
├── main/
│ ├── CMakeLists.txt # main 组件注册
│ ├── main.c # ★ 入口 app_main()
│ ├── APP/
│ │ ├── lvgl_demo.c # ★ LVGL 移植核心 (显示/触摸/刷新/任务) → lvgl.md
│ │ ├── lvgl_demo.h # 公开接口声明
│ │ ├── lv_mainstart.c/.h # 文件浏览器 Demo
│ │ └── demo.c # 额外 Demo 页面
│ └── DEMO1/ # NXP GUI Guider 仪表盘 Demo
└── components/
├── BSP/
│ ├── SPILCD/ # ★ SPI/QSPI LCD 驱动核心 → lcd.md
│ │ ├── qspi.c # SPI/QSPI 底层传输函数
│ │ ├── qspi.h # 引脚宏 + 函数声明
│ │ ├── qspilcd.c # LCD 初始化 + 刷新回调 + CTP 复用接口
│ │ └── qspilcd.h # 配置宏 / 颜色宏 / 结构体
│ ├── TDO_CTP/ # ★ 触摸屏驱动 (多芯片适配)
│ │ ├── drv/esp32/
│ │ │ ├── esp32_ctp.c # 硬件抽象层 (I2C/GPIO/读写接口注册)
│ │ │ ├── esp32_ctp.h # 触摸引脚定义
│ │ │ └── tdo_ctp_conf.h # 芯片选择宏
│ │ ├── src/
│ │ │ ├── tdo_ctp.c # 通用 CTP 驱动框架
│ │ │ └── ctp/ # 11 种触摸芯片驱动
│ │ └── inc/
│ │ ├── tdo_ctp.h # CTP API 接口
│ │ └── tdo_def.h # 通用类型/事件定义
│ ├── LED/ # LED 驱动 (led.c/h)
│ ├── SDIO/ # SD 卡驱动 (spi_sdcard.c/h)
│ └── SPI/ # 通用 SPI 驱动 (spi.c/h)
└── LVGL/ # LVGL v8.3.11 完整源码4. 初始化顺序
4.1 总流程
app_main() (Core 0)
│
├─① initialize_nvs() NVS Flash 初始化
├─② led_init() LED 引脚配置
│
└─③ lvgl_demo() ───────────────────── ★ 主初始化入口
│
├─④ lv_init() LVGL 内核初始化
├─⑤ lv_port_disp_init() ★ 显示子系统
│ ├─ lcd_init() │ GPIO + SPI3 总线 + 设备 + 硬件复位 + LCD 初始化序列
│ ├─ heap_caps_malloc() × 2 │ PSRAM 分配两个全屏缓冲区 (各 768 KB)
│ ├─ lv_disp_draw_buf_init() │ 注册双缓冲到 LVGL
│ └─ lv_disp_drv_register() │ 注册显示驱动 (flush_cb + full_refresh=1)
│
├─⑥ lv_port_indev_init() ★ 触摸子系统
│ ├─ esp32_ctp_init() │ I2C 或 SPI 初始化 + 芯片探测
│ └─ lv_indev_drv_register() │ 注册输入驱动 (read_cb)
│
├─⑦ xSemaphoreCreateBinary() 信号量 (flush_cb → 刷新任务)
├─⑧ xSemaphoreCreateMutex() 互斥锁 (保护 g_area / g_color)
├─⑨ esp_timer_create/start() 1ms Tick 定时器 → lv_tick_inc(1)
│
├─⑩ xTaskCreate(lv_demo_task) 创建 UI 任务 (Core 1, 优先级 1, 5 KB)
└─⑪ xTaskCreate(lv_flush_task) 创建刷新任务 (Core 1, 优先级 2, 5 KB)
↓ 线程启动后 ↓
lv_demo_task lv_flush_task
├─ lv_demo_widgets() while(1):
└─ while(1): xSemaphoreTake() 阻塞
lv_timer_handler() lcd_lv_cb() → QSPI DMA
vTaskDelay(10) xSemaphoreGive(xMutex)适用平台: ESP32-S3 + IDF 5.1.2 + TR2S + LVGL v8.3.11