0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

全面解读目前LVGL的应用小知识

电子工程师 来源:华芯微特32位MCU 作者:华芯微特32位MCU 2021-06-04 12:01 次阅读

概述

本文介绍目前LVGL的应用小知识,希望对采用MCU设计UI界面的用户有所启发,开发出界面更友好的消费品或者工业产品,造福大众。

01.

LVGL系统架构

LVGL系统框架

应用程序创建GUI并处理特定任务的应用程序。

LVGL本身是一个图形库。我们的应用程序通过调用LVGL库来创建GUI。它包含一个HAL(硬件抽象层)接口,用于注册显示和输入设备驱动程序。

驱动程序除特定的驱动程序外,它还有其他的功能,可驱动显示器到GPU (可选)、读取触摸板或按钮的输入。

根据MCU,有两种典型的硬件设置。一个带有内置LCD/TFT驱动器的外围设备,而另一种是没有内置LCD/TFT驱动器的外围设备。在这两种情况下,都需要一个帧缓冲区来存储屏幕的当前图像。

1.集成了TFT/LCD驱动器的MCU如果MCU集成了TFT/LCD驱动器外围设备,则可以直接通过RGB接口连接显示器。在这种情况下,帧缓冲区可以位于内部RAM(如果MCU有足够的RAM)中,也可以位于外部RAM(如果MCU具有存储器接口)中。

2.如果MCU没有集成TFT/LCD驱动程序接口,则必须使用外部显示控制器(例如SSD1963、SSD1306、ILI9341 )。在这种情况下,MCU可以通过并行端口,SPI或通过I2C与显示控制器进行通信。帧缓冲区通常位于显示控制器中,从而为MCU节省了大量RAM。

02.

建立一个LVGL项目

要在我们的项目中使用 lvgl ,我们起码需要获取到官方的这两个库:

lvgl(lvgl)核心图形库的官方 GitHub 仓库地址:https://github.com/lvgl/lvgl。

lvgl(lv_drivers)输入输出设备驱动官方 GitHub 仓库地址:https://github.com/lvgl/lv_drivers

我们可以克隆或下载这两个库的最新版本,将它们复制到我们的项目中,然后进行适配。

目录 lvgl 就是 lvgl 的官方图形库

目录 lv_drivers 是 lvgl 输入输出设备驱动官方示例配置

目录 lv_examples 是 lvgl 的官方demo(可选,但不要直接使用到实际项目中)

配置文件

上面的三个库中有一个类似名为 lv_conf_template.h 的配置头文件(template就是模板的意思)。通过它可以设置库的基本行为,裁剪不需要模块和功能,在编译时调整内存缓冲区的大小等等。

将 lvgl/lv_conf_template.h 复制到 lvgl 同级目录下,并将其重命名为 lv_drv_conf.h 。打开文件并将开头的 #if 0 更改为 #if 1 以使能其内容。

将 lv_drivers/lv_drv_conf_template.h 复制到 lv_drivers 同级目录下,并将其重命名为 lv_conf.h 。打开文件并将开头的 #if 0 更改为 #if 1 以使能其内容。

(可选)将 lv_examples/lv_ex_conf_template.h 复制到 lv_examples 同级目录下,并将其重命名为 lv_ex_conf.h 。打开文件并将开头的 #if 0 更改为 #if 1 以使能其内容。

准备lvgl配置文件

af7f2894-c4c6-11eb-9e57-12bb97331649.png

使能配置文件

lv_conf.h 也可以复制到其他位置,但是应该在编译器选项中添加 ``LV_CONF_INCLUDE_SIMPLE``定义(例如,对于gcc编译器为``-DLV_CONF_INCLUDE_SIMPLE`` ) 并手动设置包含路径。

在配置文件中,注释说明了各个选项的含义。我们在移植时至少要检查以下三个配置选项,其他配置根据具体的需要进行修改:

LV_HOR_RES_MAX 显示器的水平分辨率。

LV_VER_RES_MAX 显示器的垂直分辨率。

LV_COLOR_DEPTH 颜色深度,其可以是:

8 - RG332

16 - RGB565

32 - (RGB888和ARGB8888)

初始化LVGL

准备好这三个库:lvgl、lv_drivers、lv_examples 后,我们就要开始使用lvgl带给我们的功能了。使用 lvgl 图形库之前,我们还必须初始化 lvlg 以及相关其他组件。初始化的顺序为:

调用 lv_init() 初始化 lvgl 库;

初始化驱动程序;

在 LVGL 中注册显示和输入设备驱动程序;

在中断中每隔 x毫秒 调用 lv_tick_inc(x) 用以告知 lvgl 经过的时间;

每隔 x毫秒 定期调用 lv_task_handler() 用以处理与 LVGL相关的任务。

03.

显示接口

要设置显示,必须初始化 lv_disp_buf_t 和 lv_disp_drv_t 变量。

lv_disp_buf_t 保存显示缓冲区信息的结构体

lv_disp_drv_t HAL要注册的显示驱动程序、与显示交互并处理与图形相关的结构体、回调函数。

显示缓存区

关于缓冲区大小,有 3 种情况:

一个缓冲区 LVGL将屏幕的内保存到缓冲区中并将其发送到显示器。缓冲区可以小于屏幕。在这种情况下,较大的区域将被重画成多个部分。如果只有很小的区域发生变化(例如按下按钮),则只会刷新该部分的区域。

两个非屏幕大小的缓冲区 具有两个缓冲区的 LVGL 可以将其中一个作为显示缓冲区,而另一缓冲区的内容发送到后台显示。应该使用 DMA 或其他硬件将数据传输到显示器,以让CPU同时绘图。这样,渲染和刷新并行处理。与 一个缓冲区 的情况类似,如果缓冲区小于要刷新的区域,LVGL将按块绘制显示内容

两个屏幕大小的缓冲区 与两个非屏幕大小的缓冲区相反,LVGL将始终提供整个屏幕的内容,而不仅仅是块。这样,驱动程序可以简单地将帧缓冲区的地址更改为从 LVGL 接收的缓冲区。因此,当MCU具有 LCD/TFT 接口且帧缓冲区只是 RAM 中的一个位置时,这种方法的效果很好。

显示驱动器

一旦缓冲区初始化准备就绪,就需要初始化显示驱动程序。在最简单的情况下,仅需要设置 lv_disp_drv_t 的以下两个字段:

buffer 指向已初始化的 lv_disp_buf_t 变量的指针。

flush_cb 回调函数,用于将缓冲区的内容复制到显示的特定区域。刷新准备就绪后,需要调用lv_disp_flush_ready()。LVGL可能会以多个块呈现屏幕,因此多次调用flush_cb。使用 lv_disp_flush_is_last() 可以查看哪块是最后渲染的。

其中,有一些可选的数据字段:

hor_res 显示器的水平分辨率。(默认为 lv_conf.h 中的 LV_HOR_RES_MAX )

ver_res 显示器的垂直分辨率。(默认为 lv_conf.h 中的 LV_VER_RES_MAX )

color_chroma_key 在 chrome 键控图像上将被绘制为透明的颜色。(默认为 lv_conf.h 中的 LV_COLOR_TRANSP )

user_data 驱动程序的自定义用户数据。可以在 lv_conf.h 中修改其类型。

anti-aliasing 使用抗锯齿(anti-aliasing)(边缘平滑)。缺省情况下默认为 lv_conf.h 中的 LV_ANTIALIAS 。

rotated 如果 1 交换 hor_res 和 ver_res 。两种情况下 LVGL 的绘制方向相同(从上到下的线条),因此还需要重新配置驱动程序以更改显示器的填充方向。

screen_transp 如果为 1 ,则屏幕可以具有透明或不透明的样式。需要在 lv_conf.h 中启用 LV_COLOR_SCREEN_TRANSP 。

要使用GPU,可以使用以下回调:

gpu_fill_cb 用颜色填充内存中的区域。

gpu_blend_cb 使用不透明度混合两个内存缓冲区。

gpu_wait_cb 如果在 GPU 仍在运行 LVGL 的情况下返回了任何 GPU 函数,则在需要确保GPU渲染就绪时将使用此函数。

注意,这些功能需要绘制到内存(RAM)中,而不是直接显示在屏幕上。

其他一些可选的回调,使单色、灰度或其他非标准RGB显示一起使用时更轻松、优化:

rounder_cb 四舍五入要重绘的区域的坐标。例如。2x2像素可以转换为2x8。如果显示控制器只能刷新特定高度或宽度的区域(对于单色显示器,通常为8 px高),则可以使用它。

set_px_cb 编写显示缓冲区的自定义函数。如果显示器具有特殊的颜色格式,则可用于更紧凑地存储像素。(例如1位单色,2位灰度等)。这样,lv_disp_buf_t中使用的缓冲区可以较小,以仅保留给定区域大小所需的位数。set_px_cb不能与两个屏幕大小的缓冲区一起显示缓冲区配置。

monitor_cb 回调函数告诉在多少时间内刷新了多少像素。

clean_dcache_cb 清除与显示相关的所有缓存的回调

要设置 lv_disp_drv_t 变量的字段,需要使用 lv_disp_drv_init(&disp_drv) 进行初始化。最后,要为 LVGL 注册显示设备,需要调用lv_disp_drv_register(&disp_drv)。

04.

输入设备接口

(一)、输入设备的类型

要设置输入设备,必须初始化 lv_indev_drv_t 变量:

afb16c3c-c4c6-11eb-9e57-12bb97331649.jpg

类型 (indev_drv.type)可以是:

LV_INDEV_TYPE_POINTER 触摸板或鼠标

LV_INDEV_TYPE_KEYPAD 键盘或小键盘

LV_INDEV_TYPE_ENCODER 带有左,右,推动选项的编码器

LV_INDEV_TYPE_BUTTON 外部按钮按下屏幕

read_cb (indev_drv.read_cb)是一个函数指针,将定期调用该函数指针以报告输入设备的当前状态。它还可以缓冲数据并在没有更多数据要读取时返回 false ,或者在缓冲区不为空时返回 true 。

进一步了解有关 输入设备 的更多信息。

(二)、触摸板,鼠标或任何指针

可以单击屏幕点的输入设备属于此类别。

即使状态为 LV_INDEV_STATE_REL ,触摸板驱动程序也必须返回最后的 X/Y 坐标。

要设置鼠标光标,请使用 lv_indev_set_cursor(my_indev,&img_cursor) 。( my_indev 是 lv_indev_drv_register 的返回值)键盘或键盘

(三)、触摸板或键盘

带有所有字母的完整键盘或带有一些导航按钮的简单键盘均属于此处。

要使用键盘/触摸板:

注册具有 LV_INDEV_TYPE_KEYPAD 类型的 read_cb 函数。

在 lv_conf.h 中启用 LV_USE_GROUP

必须创建一个对象组:lv_group_t * g = lv_group_create(),并且必须使用 lv_group_add_obj(g,obj) 向其中添加对象

必须将创建的组分配给输入设备:lv_indev_set_group(my_indev,g)( my_indev 是 lv_indev_drv_register 的返回值)

使用 LV_KEY _… 在组中的对象之间导航。有关可用的密钥,请参见 lv_core/lv_group.h。

(四)、编码器

可以通过下面四种方式使用编码器:

按下按钮

长按其按钮

转左

右转

简而言之,编码器输入设备的工作方式如下:

通过旋转编码器,可以专注于下一个/上一个对象。

在简单对象(如按钮)上按下编码器时,将单击它。

如果将编码器按在复杂的对象(如列表,消息框等)上,则该对象将进入编辑模式,从而转动编码器即可在对象内部导航。

长按按钮,退出编辑模式。

要使用编码器(类似于键盘),应将对象添加到组中。

(五)、使用带有编码器逻辑的按钮

除了标准的编码器行为外,您还可以利用其逻辑来使用按钮导航(聚焦)和编辑小部件。如果只有几个按钮可用,或者除编码器滚轮外还想使用其他按钮,这将特别方便。

需要有3个可用的按钮:

LV_KEY_ENTER 将模拟按下或推动编码器按钮

LV_KEY_LEFT 将向左模拟转向编码器

LV_KEY_RIGHT 将正确模拟转向编码器

其他键将传递给焦点小部件

如果按住这些键,它将模拟indev_drv.long_press_rep_time中指定的时间段内的编码器单击。

(六)、按键

按钮是指屏幕旁边的外部“硬件”按钮,它们被分配给屏幕的特定坐标。如果按下按钮,它将模拟在指定坐标上的按下。(类似于触摸板)

使用 lv_indev_set_button_points(my_indev, points_array) 将按钮分配给坐标。points_array应该看起来像const lv_point_t points_array [] = {{12,30},{60,90},…}

points_array不能超出范围。将其声明为全局变量或函数内部的静态变量。

(七)、其它功能

除了 read_cb 之外,还可以在 lv_indev_drv_t 中指定 feedback_cb 回调。输入设备发送任何类型的事件时,都会调用feedback_cb。(独立于其类型)。它允许为用户提供反馈,例如在LV_EVENT_CLICK上播放声音。

可以在lv_conf.h中设置以下参数的默认值,但可以在lv_indev_drv_t中覆盖默认值:

拖拽限制(drag_limit) 实际拖动对象之前要滑动的像素数 drag_throw 拖曳速度降低[%]。更高的价值意味着更快的减速

(drag_throw) 拖曳速度降低[%]。更高的价值意味着更快的减速

(long_press_time) 按下时间发送 LV_EVENT_LONG_PRESSED (以毫秒为单位)

(long_press_rep_time) 发送 LV_EVENT_LONG_PRESSED_REPEAT 的时间间隔(以毫秒为单位)

(read_task) 指向读取输入设备的lv_task的指针。可以通过 lv_task_.。。() 函数更改其参数

每个输入设备都与一个显示器关联。默认情况下,新的输入设备将添加到最后创建的或显式选择的显示设备(使用lv_disp_set_default())。相关的显示已存储,并且可以在驱动程序的显示字段中更改。

(八)、心跳

LVGL 需要系统滴答声才能知道动画和其他任务的经过时间。

为此我们需要定期调用 lv_tick_inc(tick_period) 函数,并以毫秒为单位告知调用周期。例如, lv_tick_inc(1) 用于每毫秒调用一次。

为了精确地知道经过的毫秒数,lv_tick_inc 应该在比 lv_task_handler() 更高优先级的例程中被调用(例如在中断中),即使 lv_task_handler 的执行花费较长时间。

(九)、任务处理器(Task Handler)

要处理 LVGL 的任务,我们需要定期通过以下方式之一调用 lv_task_handler() :

mian 函数中设置 while(1) 调用

定期定时中断(低优先级然后是 lv_tick_inc()) 中调用

定期执行的 OS 任务中调用

计时并不严格,但应保持大约5毫秒以保持系统响应。

05.

日志记录

LVGL 内置有日志模块,用于记录用户库中正在发生的事情。

(一)、日志级别

要启用日志记录,需要在 lv_conf.h 中将 LV_USE_LOG 设置为 1 ,并将 LV_LOG_LEVEL 设置为以下值之一:

LV_LOG_LEVEL_TRACE 记录所有信息

LV_LOG_LEVEL_INFO 记录重要事件

LV_LOG_LEVEL_WARN 记录是否发生了警告事件

LV_LOG_LEVEL_ERROR 记录错误信息,当系统可能发生故障时或致命错误

LV_LOG_LEVEL_NONE 不要记录任何东西

级别高于设置的日志级别的事件也将被记录。例如。如果使用 LV_LOG_LEVEL_WARN ,也会记录错误。

(二)、使用printf记录

如果您的系统支持printf,则只需在 lv_conf.h 中启用 **LV_LOG_PRINTF **即可发送带有 printf 的日志。

(三)、自定义日志功能

如果不能使用 printf 或想要使用自定义函数进行日志记录,可以使用 lv_log_register_print_cb() 注册 “logger” 回调。

编辑:jq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 处理器
    +关注

    关注

    68

    文章

    18288

    浏览量

    222169
  • 编码器
    +关注

    关注

    41

    文章

    3361

    浏览量

    131555
  • gpu
    gpu
    +关注

    关注

    27

    文章

    4422

    浏览量

    126711
  • 函数
    +关注

    关注

    3

    文章

    3882

    浏览量

    61310
  • LVGL
    +关注

    关注

    0

    文章

    75

    浏览量

    2404

原文标题:华芯微特小课堂--LVG免费开源GUI图形库

文章出处:【微信号:gh_ed4f95bde4df,微信公众号:华芯微特32位MCU】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    基于RA8D1的LVGL FSP配置以及使用介绍

    本文介绍由e2 studio自动生成的FSP LVGL pack的使用说明,Pack的生成方法可以参考前面的介绍文章。
    的头像 发表于 03-13 13:48 936次阅读
    基于RA8D1的<b class='flag-5'>LVGL</b> FSP配置以及使用介绍

    详解全志R128 GUI图形系统—LVGL

    LVGL 是一个免费的开源图形库,提供了创建嵌入式GUI 所需的一切,具有易于使用的图形元素,美观的视觉效果和低内存占用,采用MIT 许可协议,可以访问LittlevGL官网获取更多资料。
    的头像 发表于 12-11 14:49 1181次阅读
    详解全志R128 GUI图形系统—<b class='flag-5'>LVGL</b>篇

    基于LVGL驱动的OLED屏的FFT声音实时可视化

    本项目旨在利用LVGL驱动的 Xiao-expansion-board的OLED显示屏实现FFT声音数据的实时可视化。关键内容包括利用LVGL库在OLED屏幕上进行数据可视化展示,在XIAO ESP32S3 Sense 上进行声音数据的高速采集和预处理
    的头像 发表于 11-25 14:20 1718次阅读
    基于<b class='flag-5'>LVGL</b>驱动的OLED屏的FFT声音实时可视化

    一文解读GNSS信号对网络中授时应用的益处

    知识 | 一文解读GNSS信号对网络中授时应用的益处
    的头像 发表于 11-24 14:26 258次阅读
    一文<b class='flag-5'>解读</b>GNSS信号对网络中授时应用的益处

    LVGL案例分享--手把手教你移植到T113-i国产工业开发板

    市面上有许多嵌入式GUI库可供选择,包括开源GUI库和闭源GUI库,开源GUI库:LVGL,EmWin等;闭源GUI库:TouchGFX,柿饼GUI等。 本篇文章主要描述如何将LVGL8.1移植到创
    发表于 11-17 09:55

    蓝牙4.1新技术全面解析(附蓝牙扫盲知识)

    电子发烧友网站提供《蓝牙4.1新技术全面解析(附蓝牙扫盲知识).doc》资料免费下载
    发表于 11-10 16:26 1次下载
    蓝牙4.1新技术<b class='flag-5'>全面</b>解析(附蓝牙扫盲<b class='flag-5'>知识</b>)

    RT-Thread Studio上移植GUI-Guider-1.4开发LVGL8.2工程

    创建一个rttthread工程,选择出厂带好LVGL配置的demo,或者自己已经搭建好了LVGL环境的工程。
    的头像 发表于 11-03 12:52 751次阅读
    RT-Thread Studio上移植GUI-Guider-1.4开发<b class='flag-5'>LVGL</b>8.2工程

    SWM32SRET6——LVGL移植

    SWM32SRET6——LVGL移植
    的头像 发表于 10-26 17:33 858次阅读
    SWM32SRET6——<b class='flag-5'>LVGL</b>移植

    如何将lvgl粗略的移植到stm32f429上?

    上周将lvgl粗略的移植到stm32f429上,界面刷新问题没有好好处理,看着非常非常卡顿,今天初步处理了这个问题,效果还算可以了,后边应该是可以更进一步优化。
    的头像 发表于 10-23 16:40 1207次阅读
    如何将<b class='flag-5'>lvgl</b>粗略的移植到stm32f429上?

    如何实现一种基于LVGL的汽车仪表盘设计?

    目前在汽车仪表行业,MCU上跑的主流GUI是kanzi和CGI,SOC上主流GUI是Qt,因此想试试用LVGL在MCU上跑个汽车仪表界面。
    发表于 09-18 11:17 1327次阅读
    如何实现一种基于<b class='flag-5'>LVGL</b>的汽车仪表盘设计?

    HMI-Board开发板工程在添加新组件时LVGL组件会报错的解决办法

    在使用HMI-Board开发板开发lvgl的GUI界面设计时,可以直接在官方提供的lvgl的demo中开发,这样就可以省去lvgl最初的繁琐配置步骤,这里真的要感谢官方,将最繁琐的一步帮我们省去了,可以更加专注于
    的头像 发表于 09-13 16:17 990次阅读
    HMI-Board开发板工程在添加新组件时<b class='flag-5'>LVGL</b>组件会报错的解决办法

    LVGL开发指南(适用于正点原子STM32开发板)

    在学习 LVGL移植相关知识之前,我们需要先简单地了解一下 LVGL的初始化流程,这样 即可知道整个初始化过程中所涉及的一些关键配置,而这些关键配置是在移植过程中需要重点 关注的。LVGL
    发表于 09-06 17:38 12次下载

    如何在MDK中部署LVGL

    LVGL的刚刚完成了对LVGL8的维护更新,发布了v8.3.5版。相对master分支上正在开发的LVGL9,该版本是一个吐血推荐的稳定版本。
    的头像 发表于 07-27 14:41 806次阅读
    如何在MDK中部署<b class='flag-5'>LVGL</b>

    10分钟搞定如何在QT环境模拟LVGL V8

    LVGL是一款非常不错的开源图形界面库,易于移植,嵌入式图形界面开发中,LVGL可以说是非常受欢迎的,如何快速的模拟lvgl开发效果,快速移植到嵌入式产品中,我们可以先通过PC端模拟器开发效果,然后无缝移植到嵌入式环境中。
    的头像 发表于 05-22 10:39 3701次阅读
    10分钟搞定如何在QT环境模拟<b class='flag-5'>LVGL</b> V8

    LVGL Simulation工程

    最近在玩一个开源项目,用到ESP32,玩着玩着感觉开源项目的UI太枯燥了,于是了解到了LVGL,网上很多关于ESP32跑LVGL的现有工程
    的头像 发表于 05-11 09:12 764次阅读
    <b class='flag-5'>LVGL</b> Simulation工程