LVGL: 嵌入式GUI 小巧易用

内容分享3小时前发布
0 2 0

LVGL库的介绍

LVGL: 嵌入式GUI 小巧易用

LVGL(Light and Versatile Graphics Library)是一个免费开源的图形库,专为嵌入式系统设计,用于创建美观的用户界面(UI)。它适用于各种微控制器(MCU)、微处理器(MPU)和显示器类型,从小型单色显示屏到全高清监视器。LVGL于2016年首次发布,由一群志愿者开发,目前已成为嵌入式图形领域的热门选择,受多家行业领先厂商支持,如Arm、STM32、NXP、Espressif等。

LVGL的核心目标是提供一个轻量级、灵活的框架,协助开发者在资源有限的嵌入式设备上构建现代化的GUI。它支持C语言编写,并兼容C++,无需外部依赖即可集成到任何项目中。库的许可为MIT开源许可,即使在商业项目中也可免费使用。

LVGL的工作原理是通过缓冲区渲染UI内容,然后将缓冲区发送到显示器。它支持多种缓冲模式,以平衡内存使用和性能。开发者可以通过简单的API创建小部件(widgets)、应用样式、添加事件和动画,实现复杂的交互界面。

LVGL的特点

LVGL的设计注重轻量、高效和丰富功能,以下是其主要特点:

  • 低内存占用:最小只需32kB RAM和128kB Flash,支持至少1/10屏幕大小的渲染缓冲区。适用于资源受限的MCU。
  • 丰富的功能:内置30+小部件(如按钮、滑块、图表),支持动画、抗锯齿、透明度、平滑滚动、阴影和图像变换。
  • 灵活的样式系统:类似于CSS,提供约100种样式属性,支持状态(如按下、焦点)和部件部分(如指示器、旋钮)的自定义。
  • 多语言支持:UTF-8编码,支持CJK、泰文、印地文、阿拉伯文和波斯文,包括双向文本渲染(LTR和RTL)。
  • 输入设备兼容:支持触摸屏、鼠标、键盘、编码器和外部按钮。
  • 多显示器支持:可同时驱动多个显示器,支持不同主题(如彩色TFT和单色显示)。
  • 布局引擎:Web-inspired的Flexbox和Grid布局,支持响应式设计。
  • GPU加速:内置支持STM32 DMA2D和NXP PXP/VGLite等GPU,可自定义GPU接口。
  • 跨平台开发:可在PC模拟器上开发UI,然后移植到嵌入式硬件,支持Emscripten转换为HTML。
  • 开源与社区:MIT许可,活跃社区,提供图形设计、UI实现和咨询服务。
  • 无自定义构建系统:支持Make和CMake,直接集成到现有项目。

这些特点使LVGL成为嵌入式GUI开发的首选,尤其在IoT、智能穿戴和工业控制领域。

详细的模块分类

LVGL的模块分为核心模块、绘制模块、布局模块、小部件模块、事件模块、动画模块、字体模块和其他辅助模块。以下是详细分类:

1. 核心模块(Core)

  • 对象(Objects):所有UI元素的基类,包括屏幕、容器等。
  • 样式(Styles):定义外观,如颜色、边框、字体,支持级联和继承。
  • 事件(Events):处理用户交互,如点击、拖动,支持冒泡和自定义事件。

2. 绘制模块(Drawing)

  • 渲染引擎:支持软件渲染和GPU加速,处理抗锯齿、透明度、阴影等。
  • 缓冲模式:单缓冲、双缓冲和全屏缓冲,支持DMA传输以并行渲染。
  • 蒙版(Masking):用于复杂形状渲染,如圆角矩形。

3. 布局模块(Layouts)

  • Flex布局:类似于CSS Flexbox,支持行/列排列、换行、对齐和增长。
  • Grid布局:类似于CSS Grid,支持网格排列、跨行/列和子网格。

4. 小部件模块(Widgets)

  • 基本小部件:按钮(Button)、标签(Label)、图像(Image)、线(Line)。
  • 输入小部件:滑块(Slider)、开关(Switch)、复选框(Checkbox)、下拉列表(Dropdown)。
  • 高级小部件:图表(Chart)、表格(Table)、键盘(Keyboard)、菜单(Menu)、日历(Calendar)。
  • 其他:弧形(Arc)、条形(Bar)、LED、列表(List)、滚轮(Roller)、旋转框(Spinbox)、旋转器(Spinner)、标签视图(Tabview)、文本区域(Textarea)、图块视图(Tileview)、窗口(Window)。

5. 事件模块(Events)

  • 输入事件:按下、释放、点击、长按、拖动、手势。
  • 绘制事件:主绘制、后绘制,用于自定义渲染。
  • 其他事件:焦点、布局变化、屏幕加载、删除。
  • 特殊事件:值变化、插入文本等,小部件特定。

6. 动画模块(Animations)

  • 基本动画:线性、缓入、缓出、弹跳等路径函数。
  • 时间线:序列化多个动画,支持延迟和重复。
  • 回调:开始、执行、完成、删除回调。

7. 字体模块(Fonts)

  • 内置字体:Montserrat系列,支持ASCII和符号。
  • 自定义字体:支持位图、矢量(TrueType)、压缩字体。
  • 字体引擎:支持UTF-8、多语言、双向文本。

8. 其他模块(Others)

  • 快照(Snapshots):捕获小部件图像,支持自定义区域。
  • 文件系统:支持文件浏览和操作。
  • 猴子测试:自动化UI测试。
  • 观察者:数据绑定,支持主题更改。
  • 第三方集成:FreeType、FFmpeg、Tiny TTF等,用于高级字体和媒体。

这些模块可根据需求启用/禁用,以优化内存使用。

应用场景

LVGL适用于各种嵌入式应用场景,尤其在资源有限的环境中表现出色:

  • 物联网设备(IoT):智能家居面板、传感器显示,用于显示实时数据和控制界面。
  • 可穿戴设备:智能手表、手环,支持动画和触摸交互。
  • 工业控制:HMI(人机界面)、仪表盘、监控系统,提供图表和按钮。
  • 消费电子:MP3播放器、相机、打印机界面,支持多语言和自定义主题。
  • 医疗设备:监护仪、诊断工具,需要高可靠性UI。
  • 汽车仪表:仪表盘、导航系统,支持GPU加速和高分辨率。
  • 教育工具:电子书、学习机,支持文本渲染和动画。
  • 游戏设备:手持游戏机,支持图像和事件处理。

LVGL的低资源占用和灵活性使其适合从100MHz MCU到多核Linux MPU的平台。通过PC模拟器开发,加速原型设计。

详细各功能模块的代码示例

以下按模块分类提供代码示例。示例使用C++风格,直接嵌入文章中。

核心模块示例

对象创建

 #include <lvgl.h>
 
 void create_object() {
     lv_obj_t* obj = lv_obj_create(lv_screen_active());
     lv_obj_set_size(obj, 200, 100);
     lv_obj_center(obj);
 }

样式应用

 static lv_style_t style;
 lv_style_init(&style);
 lv_style_set_bg_color(&style, lv_palette_main(LV_PALETTE_BLUE));
 lv_style_set_border_width(&style, 2);
 
 lv_obj_add_style(obj, &style, 0);

绘制模块示例

简单矩形绘制

 lv_draw_rect_dsc_t draw_dsc;
 lv_draw_rect_dsc_init(&draw_dsc);
 draw_dsc.bg_color = lv_palette_main(LV_PALETTE_RED);
 draw_dsc.radius = 10;
 
 lv_draw_rect(&draw_ctx, &draw_dsc, &area);

缓冲模式配置

lv_conf.h中启用双缓冲:

 #define LV_DRAW_BUF_CNT 2
 #define LV_DRAW_BUF_SIZE (LV_HOR_RES * 10)

布局模块示例

Flex布局

 lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_ROW_WRAP);
 lv_obj_set_flex_align(cont, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_SPACE_EVENLY);
 
 // 添加子项
 for (int i = 0; i < 6; i++) {
     lv_obj_t* child = lv_btn_create(cont);
     lv_obj_set_size(child, 100, 50);
 }

Grid布局

 static lv_coord_t col_dsc[] = {70, 70, LV_GRID_TEMPLATE_LAST};
 static lv_coord_t row_dsc[] = {50, 50, LV_GRID_TEMPLATE_LAST};
 
 lv_obj_set_grid_dsc_array(cont, col_dsc, row_dsc);
 
 // 添加子项
 lv_obj_t* child = lv_btn_create(cont);
 lv_obj_set_grid_cell(child, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_STRETCH, 0, 1);

小部件模块示例

按钮

 lv_obj_t* btn = lv_btn_create(lv_screen_active());
 lv_obj_set_size(btn, 120, 50);
 lv_obj_center(btn);
 
 lv_obj_t* label = lv_label_create(btn);
 lv_label_set_text(label, "Click Me");
 lv_obj_center(label);

滑块

 lv_obj_t* slider = lv_slider_create(lv_screen_active());
 lv_obj_set_width(slider, 200);
 lv_obj_center(slider);
 lv_slider_set_value(slider, 50, LV_ANIM_OFF);

图表

 lv_obj_t* chart = lv_chart_create(lv_screen_active());
 lv_obj_set_size(chart, 200, 150);
 lv_obj_center(chart);
 
 lv_chart_series_t* ser = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);
 lv_chart_set_next_value(chart, ser, 10);  // 添加数据点

事件模块示例

点击事件

 static void btn_event_cb(lv_event_t* e) {
     if (lv_event_get_code(e) == LV_EVENT_CLICKED) {
         printf("Button clicked
");
     }
 }
 
 lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_CLICKED, NULL);

值变化事件

 static void slider_event_cb(lv_event_t* e) {
     lv_obj_t* slider = lv_event_get_target(e);
     int value = lv_slider_get_value(slider);
     printf("Slider value: %d
", value);
 }
 
 lv_obj_add_event_cb(slider, slider_event_cb, LV_EVENT_VALUE_CHANGED, NULL);

动画模块示例

基本动画

 lv_anim_t a;
 lv_anim_init(&a);
 lv_anim_set_var(&a, obj);
 lv_anim_set_values(&a, 0, 100);
 lv_anim_set_time(&a, 1000);
 lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)lv_obj_set_x);
 lv_anim_set_path_cb(&a, lv_anim_path_linear);
 lv_anim_start(&a);

时间线动画

 lv_anim_timeline_t* anim_timeline = lv_anim_timeline_create();
 lv_anim_timeline_add(anim_timeline, 0, &a1);  // 第一动画
 lv_anim_timeline_add(anim_timeline, 500, &a2); // 延迟500ms的第二动画
 lv_anim_timeline_start(anim_timeline);

字体模块示例

使用内置字体

 lv_style_set_text_font(&style, &lv_font_montserrat_16);

自定义字体

使用在线工具生成字体文件:

 LV_FONT_DECLARE(my_custom_font);
 lv_style_set_text_font(&style, &my_custom_font);

其他模块示例

快照

 lv_snapshot_dsc_t snap_dsc;
 lv_snapshot_dsc_init(&snap_dsc);
 lv_snapshot_take_to_buf(widget, LV_IMG_CF_TRUE_COLOR, &snap_dsc, buf, buf_size);

文件系统

 lv_fs_drv_t drv;
 lv_fs_drv_init(&drv);
 drv.file_open_cb = my_open_cb;  // 自定义打开函数
 lv_fs_drv_register(&drv);

观察者

 lv_observer_t* obs = lv_observer_create(widget, cb, user_data);
 lv_observer_set_target(obs, new_target);

这些示例展示了LVGL的核心功能。实际应用中,可根据需求组合使用。

© 版权声明

相关文章

2 条评论

  • 头像
    赤水之后 读者

    LVGL(Light and Versatile Graphics Library)是一个免费开源的图形库,专为嵌入式系统设计,用于创建美观的用户界面(UI)。它适用于各种微控制器(MCU)、微处理器(MPU)和显示器类型,从小型单色显示屏到全高清监视器。LVGL于2016年首次发布,由一群志愿者开发,目前已成为嵌入式图形领域的热门选择,受多家行业领先厂商,如Arm、STM32、NXP、Espressif等。

    无记录
    回复
  • 头像
    clytzebabe 读者

    好好好好好好好好

    无记录
    回复