1. 课程导入
1.1 LVGL到底是什么?
LVGL,全称是Light and Versatile Graphics Library。说白了,它就是一个为嵌入式设备量身打造的图形用户界面库。
我刚开始接触嵌入式GUI时,用的还是最原始的画点画线函数。那时候做个菜单,得自己算坐标、刷缓冲区,一个不小心就花屏。后来遇到LVGL,才觉得「原来嵌入式UI也能这么写」。
LVGL的核心特点,我总结为三点:
- 轻量:最低配置只需要16KB RAM、64KB Flash,就能跑起来
- 丰富:内置30+控件,按钮、滑块、图表、键盘……基本覆盖常见需求
- 开源:MIT协议,商用无压力
一句话总结:LVGL就是嵌入式界的Qt,但比Qt轻得多。
1.2 为什么选择LVGL?
市面上嵌入式GUI方案不少,比如emWin、TouchGFX、LittlevGL(LVGL的前身)。为什么我推荐LVGL?
拿我去年做的一个智能家居中控项目来说。当时需要在Cortex-M4上跑一个带动画的触摸界面,emWin授权费太贵,TouchGFX对硬件要求高。最后选了LVGL,两周就完成了原型。
我整理了一个对比表,你一看就明白:
| 特性 | LVGL | emWin | TouchGFX |
|---|---|---|---|
| 开源协议 | MIT(免费) | 商业授权(收费) | 部分免费 |
| 最低RAM | 16KB | 32KB | 64KB |
| 控件数量 | 30+ | 20+ | 25+ |
| 动画引擎 | 内置 | 需额外配置 | 内置 |
| 社区活跃度 | 高(GitHub 15k+ Star) | 低 | 中 |
你看,LVGL在资源占用和功能丰富度之间找到了很好的平衡点。而且社区活跃,遇到问题基本都能搜到答案。
我的建议:如果你的项目对成本敏感、硬件资源有限、又需要漂亮的UI,LVGL几乎是首选。
1.3 开发板选型
选开发板这事,我踩过不少坑。刚开始图便宜买了个不带LCD接口的板子,结果飞线飞得想哭。
我个人习惯把开发板分成三类:
- 入门级:STM32F4系列 + 3.5寸TFT屏,适合初学者
- 进阶级:ESP32-S3 + 带触摸的LCD,适合做物联网项目
- 高性能级:i.MX RT系列 + 5寸以上高清屏,适合复杂动画
具体推荐几款我实际用过的:
| 开发板 | 主控 | RAM | Flash | 推荐理由 |
|---|---|---|---|---|
| 正点原子潘多拉 | STM32L475 | 128KB | 512KB | 资料全,适合入门 |
| ESP32-S3-DevKitC | ESP32-S3 | 512KB | 16MB | WiFi/蓝牙,性价比高 |
| 野火i.MX RT1021 | i.MX RT1021 | 1MB | 8MB | 性能强劲,动画流畅 |
注意:选板子时一定要确认LCD接口类型。我建议选带RGB接口或SPI接口的屏,驱动起来最省事。
1.4 源码获取与目录结构解析
源码获取很简单,直接去LVGL的GitHub仓库:https://github.com/lvgl/lvgl。我习惯用git clone,方便后续更新。
git clone https://github.com/lvgl/lvgl.git
cd lvgl
git checkout v8.3.0 # 建议用稳定版
下载完后,我们来看看目录结构。我第一次打开时也懵了一下,但摸清楚规律后就好办了。
下面这张图是我画的LVGL源码结构图,帮你快速建立全局认知:
嗯,这里要注意几个关键目录:
- src/core/:LVGL的心脏,对象系统、事件处理、动画引擎都在这里
- src/widgets/:所有控件的实现,你用的按钮、标签、列表都在这
- src/hal/:硬件抽象层,移植时主要改这里
- src/draw/:渲染引擎,负责把控件画到屏幕上
我的经验:刚开始不用看所有代码。先看examples/里的demo,跑起来再说。遇到不懂的再回src/里查。
1.5 环境搭建实战
环境搭建其实就三步:
- 准备编译器:我习惯用ARM GCC,免费又好用
- 配置工程:把LVGL源码加进工程,设置好包含路径
- 编写移植层:实现显示屏和触摸屏的驱动接口
这里给一个最简单的main.c框架:
#include "lvgl.h"
#include "lv_port_disp.h"
#include "lv_port_indev.h"
int main(void)
{
/* 硬件初始化 */
lv_init();
/* 显示屏移植 */
lv_port_disp_init();
/* 触摸屏移植 */
lv_port_indev_init();
/* 创建一个简单的按钮 */
lv_obj_t *btn = lv_btn_create(lv_scr_act());
lv_obj_set_size(btn, 100, 50);
lv_obj_center(btn);
lv_obj_t *label = lv_label_create(btn);
lv_label_set_text(label, "Hello LVGL");
lv_obj_center(label);
/* 主循环 */
while(1) {
lv_timer_handler();
delay(5);
}
}
避坑指南:我曾经在lv_timer_handler()里忘了加延时,结果CPU跑满,屏幕还闪烁。记得加个5-10ms的延时。