2. 创建第一个LVGL界面
任务目标
在ESP32上运行LVGL,创建一个包含标签和按钮的界面。点击按钮时,标签文本在“Hello LVGL”和“Button Pressed!”之间切换。
环境依赖
本案例基于ESP-IDF v5.x + LVGL v8.3,使用lvgl和esp_lcd组件。在idf.py menuconfig中确认LCD屏驱动(如ILI9341)和触摸(如XPT2046)已正确配置。若使用模拟器,可跳过硬件配置,直接编译运行。
关键完整代码
// main.c
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "lvgl.h"
#include "lv_port_disp.h"
#include "lv_port_indev.h"
static const char *TAG = "lvgl_demo";
static lv_obj_t *label;
static lv_obj_t *btn;
static bool is_pressed = false;
static void btn_event_cb(lv_event_t *e) {
(void)e;
is_pressed = !is_pressed;
if (is_pressed) {
lv_label_set_text(label, "Button Pressed!");
} else {
lv_label_set_text(label, "Hello LVGL");
}
}
static void create_ui(void) {
// 创建标签
label = lv_label_create(lv_scr_act());
lv_label_set_text(label, "Hello LVGL");
lv_obj_align(label, LV_ALIGN_CENTER, 0, -40);
// 创建按钮
btn = lv_btn_create(lv_scr_act());
lv_obj_set_size(btn, 120, 50);
lv_obj_align(btn, LV_ALIGN_CENTER, 0, 40);
lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_CLICKED, NULL);
// 按钮上的标签
lv_obj_t *btn_label = lv_label_create(btn);
lv_label_set_text(btn_label, "Click Me");
lv_obj_center(btn_label);
}
void app_main(void) {
ESP_LOGI(TAG, "Starting LVGL demo");
// 初始化显示和输入设备(由lv_port提供)
lv_port_disp_init();
lv_port_indev_init();
// 创建UI
create_ui();
// LVGL主循环
while (1) {
lv_timer_handler();
vTaskDelay(pdMS_TO_TICKS(5));
}
}
运行与验证
- 编译烧录:在项目目录执行
idf.py build flash monitor。 - 操作:屏幕中央显示“Hello LVGL”文本,下方为“Click Me”按钮。点击按钮后,上方文本切换为“Button Pressed!”,再次点击恢复为“Hello LVGL”。
- 通过条件:每次点击按钮,标签文本在两种状态间正确切换,无卡死或乱码,即判定通过。
常见问题
- 屏幕无显示:检查
lv_port_disp_init()中的LCD引脚配置和SPI时钟频率是否与硬件匹配。 - 点击无响应:确认触摸驱动已初始化,且
lv_port_indev_init()正确注册了输入设备。 - 编译报错:确保LVGL版本为v8.3,且
lv_conf.h中启用了LV_COLOR_DEPTH和所需字体。