跳转到内容

LVGL 安装与 ESP32 配置

LVGL 安装与 ESP32 配置

本节介绍如何在 ESP32 开发环境中安装和配置 LVGL 图形库。学习完成后,您将能够:

  • 在 PlatformIO 和 Arduino IDE 中安装 LVGL
  • 配置 TFT_eSPI 库以适配特定屏幕
  • 配置 LVGL 的核心参数(颜色深度、内存分配等)
  • 编写第一个 LVGL 显示测试程序

在开始本节之前,请确保:

  • 已完成屏幕硬件接线
  • 已安装 PlatformIO 或 Arduino IDE
  • 了解基本的库管理操作
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
board_build.f_cpu = 240000000L
board_build.f_flash = 80000000L
board_build.flash_mode = qio
; PSRAM 支持(如硬件支持)
board_build.psram_mode = enabled
board_build.partitions = default_16MB.csv
lib_deps =
; LVGL 图形库
lvgl/lvgl@^8.3.0
; TFT 显示驱动
bodmer/TFT_eSPI@^2.5.0
; 触摸驱动(电容触摸)
; lvgl/lv_drivers@^8.3.0
; SPIFFS 文件系统(用于存储字体和图片)
; SPIFFS
; WiFi 和 MQTT
WiFi
knolleary/PubSubClient@^2.8
project/
├── src/
│ ├── main.cpp
│ ├── ui/ # LVGL UI 代码
│ │ ├── ui_main.cpp
│ │ ├── ui_main.h
│ │ ├── ui_helpers.cpp
│ │ └── ui_helpers.h
│ └── config/
│ └── lv_conf.h # LVGL 配置
├── lib/
│ └── TFT_eSPI/
│ └── User_Setup.h # TFT_eSPI 配置
├── data/ # SPIFFS 文件(字体、图片)
├── platformio.ini
└── partitions.csv
1. 安装 TFT_eSPI 库
工具 → 管理库 → 搜索 "TFT_eSPI" by Bodmer → 安装
2. 安装 LVGL 库
工具 → 管理库 → 搜索 "lvgl" by LVGL → 选择版本 8.3.x → 安装
3. 配置 TFT_eSPI
找到库文件夹:
Documents/Arduino/libraries/TFT_eSPI/
编辑或创建 User_Setup.h

TFT_eSPI 库通过 User_Setup.h 文件配置屏幕驱动和引脚:

// ==================================================
// User_Setup.h - ILI9341 + ST7789 配置示例
// ==================================================
// --- 选择驱动 IC ---
#define ILI9341_DRIVER // 注释掉不需要的驱动
// #define ST7789_DRIVER
// --- 屏幕分辨率 ---
#define TFT_WIDTH 240
#define TFT_HEIGHT 320
// --- SPI 接口配置 ---
#define TFT_CS 5 // 片选 GPIO
#define TFT_DC 2 // 数据/命令 GPIO
#define TFT_RST 4 // 复位 GPIO(-1 = 使用 ESP32 RST)
#define TFT_MOSI 23 // 主输出从输入
#define TFT_SCLK 18 // SPI 时钟
#define TFT_MISO 19 // 主输入从输出(可选,某些屏幕需要)
// --- 背光控制 ---
#define TFT_BL 25 // 背光 GPIO(PWM 控制)
// --- SPI 频率设置 ---
#define SPI_FREQUENCY 40000000 // 40MHz SPI 时钟
#define SPI_READ_FREQUENCY 20000000
#define SPI_TOUCH_FREQUENCY 2500000
// --- 字体支持 ---
#define LOAD_GLCD // 基础字体
#define LOAD_FONT2 // 16点阵
#define LOAD_FONT4 // 26点阵
// #define LOAD_FONT7 // 48点阵(大字体)
// --- SPI 传输模式 ---
#define SPI_TRANS_MODE SPI_TRANS_MODE_SIO // 标准 SPI
// #define SPI_TRANS_MODE SPI_TRANS_MODE_QIO // 快速 QSPI(需要硬件支持)

LVGL 的配置通过 lv_conf.h 文件完成。将此文件放入项目 src 目录:

// ==================================================
// lv_conf.h - LVGL 配置
// ==================================================
#if 1 // 设置为 1 启用此配置
// --- 颜色深度配置 ---
#define LV_COLOR_DEPTH 16 // 16-bit RGB565
#define LV_COLOR_16_SWAP 0 // 是否交换字节顺序
// --- 内存分配配置 ---
#define LV_MEM_CUSTOM 0 // 0 = 使用 LVGL 内置内存管理器
#define LV_MEM_SIZE (64U * 1024U) // 64KB LVGL 堆内存
// --- 显示缓冲区配置 ---
#define LV_DPI_DEFAULT 160 // 每英寸点数
#define LV_DISP_DEF_REFR_PERIOD 30 // 显示刷新间隔 (ms)
// --- 性能配置 ---
#define LV_USE_PERF_MONITOR 1 // 启用性能监视器
#define LV_USE_MEM_MONITOR 1 // 启用内存监视器
// --- 控件启用配置 ---
#define LV_USE_BTN 1 // 按钮
#define LV_USE_LABEL 1 // 标签
#define LV_USE_SLIDER 1 // 滑块
#define LV_USE_SWITCH 1 // 开关
#define LV_USE_CHART 1 // 图表
#define LV_USE_DROPDOWN 1 // 下拉菜单
#define LV_USE_IMG 1 // 图像
#define LV_USE_ARC 1 // 弧形
// --- 字体配置 ---
#define LV_FONT_MONTSERRAT_12 1 // 12px 字体
#define LV_FONT_MONTSERRAT_16 1 // 16px 字体
#define LV_FONT_MONTSERRAT_24 1 // 24px 字体
#define LV_FONT_MONTSERRAT_32 1 // 32px 字体
// --- 动画配置 ---
#define LV_USE_ANIMATION 1 // 启用动画
#define LV_USE_TRANSFORM 1 // 启用变换(缩放/旋转)
// --- 文件系统配置 ---
#define LV_USE_FS_STDIO 0 // 标准文件系统
#define LV_USE_FS_SPIFFS 1 // SPIFFS 文件系统
// --- 日志配置 ---
#define LV_USE_LOG 1 // 启用日志
#define LV_LOG_LEVEL LV_LOG_LEVEL_INFO // 日志级别
// --- 断言配置 ---
#define LV_USE_ASSERT_NULL 1 // 空指针检查
#define LV_USE_ASSERT_MEM_INTEGRITY 1 // 内存完整性检查
#endif
#include <Arduino.h>
#include <TFT_eSPI.h>
#include <lvgl.h>
// TFT 显示对象
TFT_eSPI tft = TFT_eSPI();
// LVGL 显示缓冲区
static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[TFT_WIDTH * 20]; // 1/16 屏幕缓冲区
// LVGL 显示驱动
static lv_disp_drv_t disp_drv;
// LVGL 显示刷新回调
void my_disp_flush(lv_disp_drv_t* disp, const lv_area_t* area,
lv_color_t* color_p) {
uint32_t w = (area->x2 - area->x1 + 1);
uint32_t h = (area->y2 - area->y1 + 1);
tft.startWrite();
tft.setAddrWindow(area->x1, area->y1, w, h);
tft.pushColors((uint16_t*)color_p, w * h, true);
tft.endWrite();
lv_disp_flush_ready(disp); // 通知 LVGL 刷新完成
}
void setup() {
Serial.begin(115200);
// 初始化 TFT
tft.begin();
tft.setRotation(1); // 设置旋转方向
// 初始化 LVGL
lv_init();
// 配置显示缓冲区
lv_disp_draw_buf_init(&draw_buf, buf, NULL, TFT_WIDTH * 20);
// 注册显示驱动
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = TFT_WIDTH;
disp_drv.ver_res = TFT_HEIGHT;
disp_drv.flush_cb = my_disp_flush;
disp_drv.draw_buf = &draw_buf;
lv_disp_drv_register(&disp_drv);
// 创建简单 UI
lv_obj_t* label = lv_label_create(lv_scr_act());
lv_label_set_text(label, "Hello Smart Home!");
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
Serial.println("LVGL 初始化完成");
}
void loop() {
lv_timer_handler(); // LVGL 任务处理
delay(5); // 5ms 延迟
}
#include <Wire.h>
// 电容触摸控制器 (FT6X36)
#define TOUCH_SDA 21
#define TOUCH_SCL 22
#define TOUCH_RST 33
#define TOUCH_IRQ 32
// 触摸读取回调
void my_touchpad_read(lv_indev_drv_t* indev_driver, lv_indev_data_t* data) {
uint16_t touchX, touchY;
bool touched = tft.getTouch(&touchX, &touchY, 600); // 压力阈值 600
if (touched) {
data->state = LV_INDEV_STATE_PR;
data->point.x = touchX;
data->point.y = touchY;
} else {
data->state = LV_INDEV_STATE_REL;
}
}
// 在 setup() 中添加
void setupTouch() {
// 初始化 I2C
Wire.begin(TOUCH_SDA, TOUCH_SCL);
// 注册触摸输入设备
lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = my_touchpad_read;
lv_indev_drv_register(&indev_drv);
}

问题 1: 编译错误 “lv_conf.h not found”

Section titled “问题 1: 编译错误 “lv_conf.h not found””

症状: 编译时提示找不到 lv_conf.h

原因: LVGL 库期望在包含路径中找到配置文件

解决方案:

; platformio.ini 中添加包含路径
build_flags =
-I src/config/ ; lv_conf.h 所在的目录

问题 2: 屏幕显示异常(花屏/黑屏)

Section titled “问题 2: 屏幕显示异常(花屏/黑屏)”

症状: 屏幕显示不正常,白屏或花屏

原因:

  • SPI 引脚配置错误
  • SPI 频率过高
  • 屏幕初始化时序问题

解决方案:

  1. 检查 User_Setup.h 中的引脚配置
  2. 降低 SPI 频率:#define SPI_FREQUENCY 27000000
  3. 检查屏幕供电电压(部分屏幕需要 5V VCC)
  4. 尝试不同的 tft.setRotation()

症状: 触摸响应慢,动画不流畅

原因:

  • 显示缓冲区太小
  • CPU 频率过低
  • 未使用 DMA 传输

解决方案:

  1. 增大显示缓冲区(至少 1/10 屏幕)
  2. 设置 CPU 频率为 240MHz
  3. 启用 DMA:#define SPI_DMA_ENABLED true

本节介绍了 LVGL 在 ESP32 上的安装和配置:

  1. PlatformIO/Arduino IDE:两种开发环境的安装方式
  2. TFT_eSPI 配置:通过 User_Setup.h 配置驱动 IC 和引脚
  3. LVGL 配置:通过 lv_conf.h 配置颜色深度、内存、控件等
  4. 显示初始化:注册显示驱动和刷新回调
  5. 触摸集成:添加触摸输入设备驱动