基于 ESP32S3 的 LVGL 9.4 图形库移植与 UI 开发实践分享(课程作业)
一、LVGL 图形库简介
LVGL(Light and Versatile Graphics Library)是一款开源嵌入式图形库,可用于构建美观、响应迅速的图形用户界面(GUI),广泛适配智能手表、智能家居设备、工业控制终端等嵌入式场景,具备轻量级、跨平台、易扩展的特性。
二、ESP32S3 开发板部署 LVGL 9.4 关键步骤
1. 组件安装
基于 ESP-IDF 开发环境,通过终端指令完成 LVGL 核心库及适配组件的安装:
bash
运行
idf.py add-dependency "lvgl/lvgl^9.4.0" idf.py add-dependency "espressif/esp_lvgl_port^2.6.3"安装完成后,在自动生成的idf_component.yml文件中补充触摸屏驱动依赖:
yaml
dependencies: espressif/esp_lcd_touch_ft5x06: ^1.0.62. 配置与初始化
- 在
LCD.h头文件中添加 LVGL 相关头文件引入及初始化函数声明,确保硬件层与图形库的适配; - 打开 SDK 配置编辑器,搜索并勾选
Benchmark your system选项以启用系统基准测试功能; - 按需添加字体配置,本次开发选择 16 号、24 号、26 号字体以满足界面显示需求;
- 在主函数中引入 LVGL 示例头文件:
#include "demos/lv_demos.h",为界面开发提供基础接口。
3. 布局方式说明
LVGL 支持两种核心布局方式,适配不同 UI 开发场景:
(1)绝对定位
通过lv_obj_set_x()/lv_obj_set_y()函数精准控制组件坐标,示例:
c
运行
lv_obj_set_x(btn_obj, 0); // 设置组件x轴坐标为0(2)弹性布局(Flex Layout)
- 排列方向配置:
lv_obj_set_flex_flow(lv_obj_t * obj, lv_flex_flow_t flow),用于定义组件排列方向及换行规则,如垂直列布局(从上到下排列):c
运行
lv_obj_set_flex_flow(root, LV_FLEX_FLOW_COLUMN); - 对齐方式配置:
lv_obj_set_flex_align(lv_obj_t * obj, lv_flex_align_t main_align, lv_flex_align_t cross_align, lv_flex_align_t track_align),用于控制组件对齐及间距,示例:c
运行
lv_obj_set_flex_align(root, LV_FLEX_ALIGN_CENTER, // 子元素水平居中 LV_FLEX_ALIGN_SPACE_EVENLY, // 子元素垂直间距均匀 LV_FLEX_ALIGN_CENTER); // 交叉轴居中
三、核心代码实现(主函数及 UI 逻辑)
c
运行
#include <stdio.h> #include <inttypes.h> #include "sdkconfig.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_system.h" #include "LCD/LCD.h" #include "demos/lv_demos.h" // LVGL刷新任务(必须) static void lvgl_refresh_task(void *arg) { while(1) { lv_timer_handler(); // 处理LVGL定时器/渲染任务 vTaskDelay(pdMS_TO_TICKS(5)); // 5ms刷新一次,适配320x240屏幕 } } // 事件回调函数(处理按钮/复选框交互) static void event_handler(lv_event_t * e) { lv_event_code_t code = lv_event_get_code(e); if(code == LV_EVENT_CLICKED) { ESP_LOGI("UI_EVENT", "Clicked event triggered"); } else if(code == LV_EVENT_VALUE_CHANGED) { ESP_LOGI("UI_EVENT", "Toggled event triggered"); } } // 登录界面创建函数 void lv_example_login(void) { lv_obj_t * root = lv_scr_act(); // 获取屏幕根对象 // 配置弹性布局:垂直列排列+居中对齐+均匀间距 lv_obj_set_flex_flow(root, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(root, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_all(root, 20, LV_PART_MAIN); // 根对象内边距 // 文本标签(解决文本框单独置顶白屏问题) lv_obj_t *label_title = lv_label_create(root); lv_label_set_text(label_title, "Login"); // 标题文本(英文) lv_obj_set_style_text_font(label_title, &lv_font_montserrat_24, LV_PART_MAIN); // 账号输入文本框 lv_obj_t *textarea_account = lv_textarea_create(root); lv_textarea_set_placeholder_text(textarea_account, "please input account"); lv_textarea_set_one_line(textarea_account, true); // 单行模式 lv_obj_set_size(textarea_account, 280, 40); // 适配320x240屏幕 // 密码输入文本框 lv_obj_t *textarea_pwd = lv_textarea_create(root); lv_textarea_set_placeholder_text(textarea_pwd, "please input password"); lv_textarea_set_one_line(textarea_pwd, true); lv_textarea_set_password_mode(textarea_pwd, true); // 密码隐藏模式 lv_obj_set_size(textarea_pwd, 280, 40); // 同意条款复选框 lv_obj_t * cb_agree = lv_checkbox_create(root); lv_checkbox_set_text(cb_agree, "I agree to the terms of service"); lv_obj_add_event_cb(cb_agree, event_handler, LV_EVENT_ALL, NULL); lv_obj_set_width(cb_agree, 280); // 登录按钮 lv_obj_t * btn_login = lv_button_create(root); lv_obj_add_event_cb(btn_login, event_handler, LV_EVENT_ALL, NULL); lv_obj_remove_flag(btn_login, LV_OBJ_FLAG_PRESS_LOCK); lv_obj_set_size(btn_login, 240, 30); // 按钮文本 lv_obj_t *label_btn = lv_label_create(btn_login); lv_label_set_text(label_btn, "login"); lv_obj_center(label_btn); } // 主函数入口 void app_main(void) { // 硬件初始化 bsp_i2c_init(); // I2C总线初始化 pca9557_init(); // IO扩展芯片初始化 bsp_lcd_init(); // LCD屏幕初始化(关键,避免白屏) // 启动LVGL bsp_lvgl_start(); // 创建LVGL刷新任务(优先级5,避免界面卡顿) xTaskCreate(lvgl_refresh_task, "lvgl_refresh", 4096, NULL, 5, NULL); // 创建登录界面 lv_example_login(); // 主循环 while (1) { vTaskDelay(pdMS_TO_TICKS(1000)); } }四、登录界面开发问题与现象记录
基于上述配置开发登录界面时,选用文本框、复选框、按钮三类核心组件,计划按 “文本框→复选框→按钮” 的顺序垂直排列。开发过程中发现关键问题:单独将文本框置于界面最上方时,程序烧录至 ESP32S3 开发板后屏幕呈现白屏状态,无任何 UI 元素显示;仅在文本框上方额外添加一个文本标签(如 “Login”)后,整个界面才能正常渲染,各组件按预期顺序显示。
五、参考资源
LVGL 相关组件及开发文档可参考百问网开源资源:http://lvgl.100ask.net/9.2/
总结
本次实践完成了 LVGL 9.4 在 ESP32S3 开发板的移植与基础 UI 开发,验证了弹性布局在嵌入式界面开发中的实用性,但仍存在文本框单独置顶导致白屏的异常现象,后续将进一步排查硬件初始化顺序、LVGL 组件渲染机制等方面的原因,以解决该兼容性问题。
