简介¶
LVGL(Light and Versatile Graphics Library)是一个免费且开源的图形库,提供了创建嵌入式 GUI 所需的一切功能,包括易于使用的图形元素、美观的视觉效果以及低内存占用。
主要特性¶
强大的构建模块,例如按钮、图表、列表、滑块、图像等
高级图形功能,包括动画、抗锯齿、不透明度、平滑滚动
支持多种输入设备,例如触摸板、鼠标、键盘、编码器等
支持多语言,采用 UTF-8 编码
支持多显示器,例如同时使用多个 TFT 和单色显示器
完全可自定义的图形元素,具有类似 CSS 的样式
硬件无关:可与任何微控制器或显示器配合使用
可扩展:能够在低内存环境下运行(64 kB Flash,16 kB RAM)
支持但不依赖操作系统、外部存储和 GPU
即使使用高级图形效果,也支持单帧缓冲操作
使用 C 编写,具有最大兼容性(兼容 C++)
模拟器可在没有嵌入式硬件的情况下在 PC 上开始嵌入式 GUI 设计
支持 MicroPython 绑定
提供教程、示例和主题以快速设计 GUI
文档可在线访问,也可下载为 PDF
免费且开源,采用 MIT 许可证
要求¶
基本上,任何能够驱动显示器的现代控制器都适合运行 LVGL。最低要求如下:
16、32 或 64 位微控制器或处理器
推荐时钟速度 > 16 MHz
Flash/ROM:> 64 kB(用于基本组件,推荐 > 180 kB)
RAM:
静态 RAM 使用量:约 2 kB,具体取决于使用的功能和对象类型
堆栈:> 2 kB(推荐 > 8 kB)
动态数据(堆):> 4 kB(如果使用多个对象,推荐 > 48 kB)。通过
LV_MEM_SIZE在lv_conf.h中设置。显示缓冲区:> "水平分辨率" 像素(推荐 > 10 × "水平分辨率")
MCU 或外部显示控制器中的一个帧缓冲区
C99 或更新版本的编译器
基本 C(或 C++)知识:
注意:内存使用量可能因架构、编译器和构建选项而异。
许可证¶
LVGL 项目(包括所有存储库)采用 MIT 许可证。 这意味着您甚至可以在商业项目中使用它。
这不是强制性的,但如果您在论坛的 我的项目 分类中或通过 lvgl.io 私信写几句话介绍您的项目,我们将非常感激。
尽管您可以免费获得 LVGL,但其背后有大量的工作。这是由一群志愿者在他们的空闲时间创建并提供给您的。
为了使 LVGL 项目可持续发展,请考虑为项目做贡献。 您可以选择多种不同的贡献方式,例如简单地发一条关于您使用 LVGL 的推文、修复错误、翻译文档,甚至成为维护者。
存储库布局¶
LVGL 项目的所有存储库都托管在 GitHub 上:https://github.com/lvgl
您将在那里找到以下存储库:
lv_drivers 显示和输入设备驱动程序
blog 博客网站的源码(https://blog.lvgl.io)
sim 在线模拟器网站的源码(https://sim.lvgl.io)
lv_port_... LVGL 的开发板或环境移植
lv_binding_.. 绑定到其他语言
发布策略¶
核心存储库遵循 语义化版本控制 的规则:
主版本用于不兼容的 API 更改。例如 v5.0.0、v6.0.0
次版本用于新的但向后兼容的功能。例如 v6.1.0、v6.2.0
补丁版本用于向后兼容的错误修复。例如 v6.1.1、v6.1.2
每次发布都会创建类似 vX.Y.Z 的标签。
发布周期¶
错误修复:按需发布,甚至每周一次
次版本发布:每 3-4 个月
主版本发布:大约每年一次
分支¶
核心存储库至少有以下分支:
master最新版本,补丁直接合并到此处。release/vX.Y次版本的稳定版本fix/some-description用于错误修复的临时分支feat/some-description用于新功能的临时分支
更新日志¶
更改记录在 CHANGELOG.md 中。
版本支持¶
在 v8 之前,每个主系列的最后一个次版本支持 1 年。 从 v8 开始,每个次版本支持 1 年。
| 版本 | 发布日期 | 支持结束日期 | 活跃状态 |
|---|---|---|---|
| v5.3 | 2019 年 2 月 1 日 | 2020 年 2 月 1 日 | 否 |
| v6.1 | 2019 年 11 月 26 日 | 2020 年 11 月 26 日 | 否 |
| v7.11 | 2021 年 3 月 16 日 | 2022 年 3 月 16 日 | 否 |
| v8.0 | 2021 年 6 月 1 日 | 2022 年 6 月 1 日 | 是 |
| v8.1 | 2021 年 11 月 10 日 | 2022 年 11 月 10 日 | 是 |
| v8.2 | 2022 年 1 月 31 日 | 2023 年 1 月 31 日 | 是 |
| v8.3 | 开发中 |
常见问题¶
我可以在哪里提问?¶
您可以在论坛提问:https://forum.lvgl.io/。
我们使用 GitHub 问题 进行与开发相关的讨论。 仅当您的问题或问题与库的开发密切相关时才使用它们。
在发布问题之前,请阅读此常见问题部分,因为您可能会在此处找到问题的答案。
我的 MCU/硬件是否受支持?¶
任何能够通过并行端口、SPI、RGB 接口或其他方式驱动显示器并满足要求的 MCU 都受 LVGL 支持。
这包括:
“常见” MCU,例如 STM32F、STM32H、NXP Kinetis、LPC、iMX、dsPIC33、PIC32、SWM341 等
蓝牙、GSM、Wi-Fi 模块,例如 Nordic NRF 和 Espressif ESP32
带有帧缓冲设备(如 /dev/fb0)的 Linux。这包括树莓派等单板计算机
任何其他具有足够强大 MCU 和驱动显示器的外设的设备
我的显示器是否受支持?¶
LVGL 只需要一个简单的驱动函数,将像素数组复制到显示器的指定区域。 如果您可以使用显示器完成此操作,那么您可以将其与 LVGL 一起使用。
支持的显示器类型示例:
具有 16 或 24 位颜色深度的 TFT
带 HDMI 接口的显示器
小型单色显示器
灰度显示器
甚至 LED 矩阵
或任何其他可以控制像素颜色/状态的显示器
请参阅 移植 部分了解更多信息。
LVGL 无法启动、随机崩溃或显示器上没有绘制任何内容。可能是什么问题?¶
为什么我的显示驱动程序没有被调用?我可能遗漏了什么?¶
确保您在中断中调用了 lv_tick_inc(x),并在主 while(1) 中调用了 lv_timer_handler()。
了解更多信息,请参阅 Tick 和 Timer handler 部分。
为什么显示驱动程序只被调用了一次?只有显示器的上部被刷新。¶
确保您在 "显示刷新回调" 的末尾调用了 lv_disp_flush_ready(drv)。
为什么屏幕上显示的是乱码?¶
可能是您的显示驱动程序中存在错误。尝试以下代码而不使用 LVGL。您应该会看到一个带有红蓝渐变的方块。
#define BUF_W 20
#define BUF_H 10
lv_color_t buf[BUF_W * BUF_H];
lv_color_t * buf_p = buf;
uint16_t x, y;
for(y = 0; y < BUF_H; y++) {
lv_color_t c = lv_color_mix(LV_COLOR_BLUE, LV_COLOR_RED, (y * 255) / BUF_H);
for(x = 0; x < BUF_W; x++){
(*buf_p) = c;
buf_p++;
}
}
lv_area_t a;
a.x1 = 10;
a.y1 = 40;
a.x2 = a.x1 + BUF_W - 1;
a.y2 = a.y1 + BUF_H - 1;
my_flush_cb(NULL, &a, buf);
为什么屏幕上显示的是无意义的颜色?¶
可能是 LVGL 的颜色格式与您的显示器的颜色格式不兼容。检查 lv_conf.h 中的 LV_COLOR_DEPTH。
如果您使用的是带 SPI(或其他字节导向接口)的 16 位颜色,可能需要在 lv_conf.h 中将 LV_COLOR_16_SWAP 设置为 1。
它会交换像素的高字节和低字节。
如何加速我的 UI?¶
打开编译器优化,并启用 MCU 的缓存(如果有)
增大显示缓冲区的大小
使用两个显示缓冲区,并在后台使用 DMA(或类似外设)刷新缓冲区
如果您使用 SPI 或并行端口驱动显示器,请增加其时钟速度
如果您的显示器有 SPI 接口,考虑更换为具有并行接口的型号,因为它具有更高的吞吐量
将显示缓冲区放在内部 RAM(而不是外部 SRAM)中,因为 LVGL 经常使用它,并且它应该具有快速访问时间
如何减少 Flash/ROM 使用量?¶
您可以在 lv_conf.h 中禁用所有未使用的功能(例如动画、文件系统、GPU 等)和对象类型。
如果您使用的是 GCC/CLANG,可以添加 -fdata-sections -ffunction-sections 编译器标志和 --gc-sections 链接器标志,以从最终二进制文件中删除未使用的函数和变量。如果可能,添加 -flto 编译器标志以启用链接时优化,并与 GCC 的 -Os 或 CLANG 的 -Oz 一起使用。
如何减少 RAM 使用量?¶
降低显示缓冲区的大小
在 lv_conf.h 中减少
LV_MEM_SIZE。此内存用于创建按钮、标签等对象。为了使用较低的
LV_MEM_SIZE,您可以仅在需要时创建对象,并在不再需要时删除它们。