机器人设计与应用综合实训技术分享 –

 ESP32 LVGL 进阶应用

适配开发环境:ESP-IDF、LVGL 9.4.0、GUI-Guider

前置基础:ESP32-LVGL 基础环境配置与移植、LCD 硬件驱动开发

文档性质:技术博客模板 | 实训报告辅助 | 工程实操复盘表

一、今日学习核心内容

在昨日完成 ESP32-LVGL 基础环境配置、硬件适配与基础控件开发的基础上,今日开展 LVGL 进阶应用开发,核心学习内容包含四大模块,实现从可视化界面设计到硬件实际运行的全流程开发,具体如下:

GUI-Guider 可视化工具使用,完成 LCD 屏幕小插件的界面绘制与工程导出;

LVGL 中文字体文件的制作、导入与调用,实现中文正常显示;

LVGL 定时器的创建、配置与功能实现,完成界面实时数据刷新;

导出代码的 ESP32 工程整合、编译调试与开发板烧录运行。

二、GUI-Guider 绘制 LCD 小插件实操流程

2.1 前期准备

安装 GUI-Guider 软件(适配 LVGL 9.4.0 版本),完成与 ESP-IDF 的环境关联;

新建工程,配置屏幕参数:匹配实际 LCD 硬件的分辨率(如 320*240)、颜色深度,选择 LVGL 9.4.0 作为内核版本;

配置工程保存路径:延续纯英文 / 数字无空格规则,避免环境兼容问题。

2.2 小插件界面绘制

本次设计 LCD 基础功能小插件,包含时间显示区、功能按钮区、状态提示区三大模块,绘制步骤如下:

从左侧控件库拖入标签(Label) 控件,作为时间显示与状态提示载体,设置字体、字号、颜色等基础样式;

拖入按钮(Button) 控件,创建 2 个功能按钮,分别命名为 “开始”“重置”,设置按钮大小、位置与点击样式;

拖入线条(Line) 控件,完成各区域的分隔,优化界面布局;

通过对齐工具将所有控件居中 / 均匀分布,匹配 LCD 屏幕实际显示区域,避免控件超出显示范围。

2.3 工程导出与代码整理

绘制完成后,点击软件顶部Export,选择ESP-IDF工程格式,导出至本地 ESP32 工程的components目录下;

导出后生成核心文件:gui_guider.c、gui_guider.h、lvgl_ui.c、lvgl_ui.h,包含界面所有控件的创建、样式与布局代码;

检查导出代码的路径与头文件引用,确保无绝对路径引用,避免后续编译路径报错。

三、LVGL 中文字体文件导入与调用

3.1 中文字体文件制作

使用 LVGL 官方Font Converter工具制作适配的中文字体文件,步骤如下:

打开 Font Converter 工具,选择需要的中文字体(如宋体、微软雅黑),设置字号(如 16 号、24 号);

选择需要的中文字符集(如数字、常用汉字、时间相关汉字:时、分、秒),减少字体文件体积,适配 ESP32 闪存空间;

配置输出格式为C 文件,选择 LVGL 9.x 版本兼容模式,生成font_zh.c和font_zh.h字体文件。

3.2 工程导入与配置

将生成的字体文件复制到 ESP32 工程的main目录下;

在CMakeLists.txt文件中添加字体文件编译项:set(SOURCES main.c gui_guider.c lvgl_ui.c font_zh.c),确保编译器识别字体文件;

在需要显示中文的文件中引入头文件:#include "font_zh.h"。

3.3 中文字体调用

在标签控件创建 / 修改时,绑定自定义中文字体,核心代码如下:// 为时间显示标签设置中文字体与初始文本

lv_label_set_font(lv_ui.label_time, &font_zh_24); // 绑定24号中文字体

lv_label_set_text(lv_ui.label_time, "当前时间:00:00:00"); // 显示中文

四、LVGL 定时器创建与功能实现

4.1 定时器核心功能

创建 LVGL 软件定时器,实现1000ms(1 秒) 定时刷新,完成界面时间的实时更新,替代传统延时方式,避免界面卡顿。

4.2 定时器代码定义与实现

4.2.1 头文件与全局变量声明(在gui_guider.h中添加)

#ifndef GUI_GUIDER_H

#define GUI_GUIDER_H

#include "lvgl.h"

#include "lvgl_ui.h"

#include "font_zh.h"

// 全局定时器句柄

extern lv_timer_t *time_timer;

// 时间计数全局变量

extern uint8_t hour, min, sec;

// 定时器回调函数声明

void time_timer_cb(lv_timer_t *timer);

// 定时器创建函数声明

void lvgl_timer_create(void);

#endif

五、问题排查与解决复盘

5.1 问题 1:CMake 文件编译报错

问题现象

整合 GUI-Guider 导出代码与中文字体文件后,执行idf.py build,CMake 编译提示文件未找到,无法识别gui_guider.c、font_zh.c等新增文件。

根因分析

CMakeLists.txt 文件未添加新增源文件的编译项,编译器无法扫描到工程中的新文件,导致编译失败。

解决方法

打开工程main目录下的CMakeLists.txt,修改SOURCES配置项,添加所有新增源文件,核心配置代码

经验总结

每次向工程中添加新的.c文件,必须在CMakeLists.txt中同步更新编译项,确保编译器识别;建议按功能分类整理源文件,便于后续维护。

5.2 问题 2:main.c 文件编译报错

问题现象

添加定时器代码后,main.c 编译提示定时器函数未声明、UI 控件变量未定义,报错信息为undefined reference to xxx。

根因分析

未引入定时器与 GUI-Guider 的头文件,编译器无法识别函数与全局变量声明;

部分定时器相关变量未定义为全局变量,跨文件调用时无法访问;

GUI-Guider 导出的 UI 控件变量(如lv_ui.label_time)未正确引入。

解决方法

  1. 在main.c顶部引入所有新增头文件:

c

运行

#include "gui_guider.h"

#include "lvgl_ui.h"

#include "font_zh.h"

  1. 将定时器句柄、时间计数变量定义为全局变量,确保跨文件调用;
  2. 检查 GUI-Guider 导出的lvgl_ui.h文件,确认控件变量lv_ui已正确定义并声明。

经验总结

跨文件调用函数 / 变量时,必须满足“头文件声明 + 源文件实现” 规则;全局变量尽量集中管理,避免分散定义导致的调用错误。

5.3 问题 3:添加定时器代码后编译才成功

问题现象

未添加定时器代码时,工程编译提示存在未引用的变量 / 函数,添加定时器完整代码(声明 + 实现 + 调用)后,编译成功。

根因分析

GUI-Guider 导出的界面代码中,时间显示标签label_time已创建,但未在工程中进行任何调用,编译器检测到未使用的变量,触发警告 / 报错;添加定时器代码后,对该标签进行了文本更新操作,变量被正常引用,编译通过。

解决方法

按要求完成定时器代码的完整定义与调用,实现控件的实际功能;

若存在暂时未使用的控件,可在代码中添加临时引用代码,或在menuconfig中关闭编译器的 “未使用变量警告”。

经验总结

LVGL 可视化设计的控件,若在工程中未进行任何功能绑定 / 调用,易触发编译器警告,建议绘制的控件均实现对应功能,避免无效控件创建。

六、工程整合与开发板烧录运行

6.1 工程核心文件整合

将今日新增文件与原有 LVGL 基础工程整合,main目录下核心文件结构如下:

plaintext

main/

├── CMakeLists.txt  // 编译配置文件(已更新)

├── main.c          // 主函数(已修改,添加定时器调用)

├── LCD.c/LCD.h     // 原有LCD硬件驱动文件

├── gui_guider.c/gui_guider.h  // GUI-Guider导出界面代码

├── lvgl_ui.c/lvgl_ui.h        // GUI-Guider导出UI控件定义

├── font_zh.c/font_zh.h        // 自定义中文字体文件

6.2 编译与烧录

打开 ESP-IDF 终端,进入工程根目录,执行idf.py reconfigure重新加载配置;

执行idf.py build编译工程,确认无报错后,连接 ESP32 开发板与电脑;

执行idf.py -p COMx flash monitor(COMx 为开发板串口号),完成代码烧录并打开串口监视器。

6.3 实测运行效果

开发板上电后,LCD 屏幕正常显示 GUI-Guider 绘制的小插件界面,布局无偏移、无乱码;

中文字体正常显示,“当前时间:00:00:00” 清晰可见;

定时器正常工作,时间每秒自动刷新,秒数、分钟、小时逐级进位,无卡顿;

点击 “开始”“重置” 按钮,界面响应灵敏,可实现时间的启停与清零(需绑定按钮事件回调);

串口监视器无报错信息,工程运行稳定,无内存溢出、程序崩溃问题。

七、今日实训收获

7.1 工具使用能力

掌握 LVGL 可视化设计工具GUI-Guider的核心使用方法,完成界面绘制、工程配置与代码导出,实现 “所见即所得” 的界面开发,大幅降低手写 UI 代码的工作量;

学会 LVGLFont Converter字体制作工具的使用,能根据实际需求制作轻量化中文字体文件,适配嵌入式设备资源限制。

7.2 代码开发与整合能力

掌握 LVGL 中文字体的导入、配置与调用方法,解决 LVGL 默认无中文字体的问题,实现中文界面显示;

理解 LVGL 软件定时器的工作原理,掌握定时器的创建、回调函数编写、初始化调用全流程,实现界面实时数据刷新,替代传统阻塞式延时,优化界面流畅度;

学会将第三方工具(GUI-Guider)导出的代码与 ESP32 原有工程整合,掌握CMakeLists.txt的编译配置技巧,解决跨文件调用、文件未识别等编译问题。

7.3 问题解决能力

积累了 ESP-IDF 工程中CMake 编译报错、头文件 / 变量未定义等常见问题的排查思路,核心遵循 “检查配置文件→检查头文件引用→检查变量 / 函数作用域” 的排错流程;

理解了编译器 “未使用变量” 报错的触发原因,掌握了对应的解决方法,规范了代码编写习惯;

进一步巩固了 “纯英文路径”“头文件保护宏” 等 ESP32 开发的基础规范,从源头规避环境兼容问题。

7.4 硬件软件协同能力

实现了“GUI-Guider 可视化设计→代码导出→工程整合→编译调试→开发板运行” 的全流程闭环,理解了可视化设计工具与底层硬件开发的适配逻辑,提升了 LVGL 与 ESP32 硬件的协同开发能力。

八、后续学习规划

完善 LCD 小插件的功能,为 “开始”“重置” 按钮绑定事件回调函数,实现时间的启停、清零与手动设置;

学习 LVGL数据可视化控件(如进度条、仪表盘、图表)的开发,实现传感器数据(如温湿度)的界面实时显示;

结合 ESP32 的外设(如按键、传感器、蓝牙),实现“硬件输入→LVGL 界面显示→界面操作→硬件控制” 的双向交互;

学习 LVGL 界面的动画效果与页面切换设计,优化界面的交互体验与视觉效果;

掌握 LVGL 工程的代码优化与裁剪方法,进一步减小程序体积,降低 ESP32 的 CPU 与闪存占用。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐