目录
LVGL文档中文网站
系统总览
应用 程序 创建 GUI 并处理特定任务的应用程序。
LVGL 图形库本身。您的应用程序可以与库通信以创建 GUI。它包含一个 HAL(硬件抽象层)接口来注册您的显示和输入设备驱动程序。
驱动程序 除了您的特定驱动程序之外,它还包含驱动您的显示器的功能,可选择驱动到 GPU 并读取触摸板或按钮。
根据 MCU 的不同,有两种典型的硬件设置。一个带有内置 LCD/TFT 驱动器外围,另一个没有它。在这两种情况下,都需要一个帧缓冲区来存储屏幕的当前图像。
-
带TFT/LCD 驱动 的MCU 如果您的MCU 有TFT/LCD 驱动外围,那么您可以通过RGB 接口直接连接显示器。在这种情况下,帧缓冲区可以位于内部 RAM(如果 MCU 有足够的 RAM)或外部 RAM(如果 MCU 有存储器接口)中。
-
外部显示控制器 如果 MCU 没有 TFT/LCD 驱动器接口,则必须使用外部显示控制器(例如 SSD1963、SSD1306、ILI9341)。在这种情况下,MCU 可以通过并行端口、SPI 或 I2C 与显示控制器通信。帧缓冲区通常位于显示控制器中,可为 MCU 节省大量 RAM。
设置项目
获取图书馆
LVGL 图形库可在 GitHub 上获得:https : //github.com/lvgl/lvgl。
您可以克隆它或从 GitHub 下载最新版本的库。
图形库是lvgl目录,应复制到您的项目中。
配置文件
有一个名为lv_conf.h 的 LVGL配置头文件。它设置库的基本行为,禁用未使用的模块和功能,在编译时调整内存缓冲区的大小等。
将lvgl/lv_conf_template.h复制到lvgl目录旁边,并将其重命名为lv_conf.h。打开文件并将开头更改为以启用其内容。
#if 0#if 1lv_conf.h也可以复制到其他地方,但是您应该将
LV_CONF_INCLUDE_SIMPLE定义添加到您的编译器选项(例如-DLV_CONF_INCLUDE_SIMPLE对于 gcc 编译器)并手动设置包含路径。在配置文件的注释中解释了选项的含义。至少检查这三个配置选项并根据您的硬件进行修改:
-
LV_HOR_RES_MAX显示器的水平分辨率。
-
LV_VER_RES_MAX显示器的垂直分辨率。
-
LV_COLOR_DEPTH 8 表示(RG332),16 表示(RGB565)或 32 表示(RGB888 和 ARGB8888)。
初始化
要使用图形库,您必须初始化它和其他组件。初始化的顺序是:
-
调用lv_init()。
-
初始化您的驱动程序。
-
lv_tick_inc(x)在x中断中每毫秒调用一次以告诉经过的时间。了解更多。 -
lv_task_handler()每隔几毫秒定期调用以处理 LVGL 相关任务。了解更多。显示界面
要设置显示的
lv_disp_buf_t和lv_disp_drv_t变量的初始化。-
lv_disp_buf_t包含内部图形缓冲区。
-
lv_disp_drv_t包含回调函数来与显示交互和操作绘图相关的东西。
显示缓冲区
lv_disp_buf_t可以这样初始化:/*A static or global variable to store the buffers*/ static lv_disp_buf_t disp_buf; /*Static or global buffer(s). The second buffer is optional*/ static lv_color_t buf_1[MY_DISP_HOR_RES * 10]; static lv_color_t buf_2[MY_DISP_HOR_RES * 10]; /*Initialize `disp_buf` with the buffer(s) */ lv_disp_buf_init(&disp_buf, buf_1, buf_2, MY_DISP_HOR_RES*10);关于缓冲区大小,有 3 种可能的配置:
-
一个缓冲区LVGL 将屏幕内容绘制到一个缓冲区中并将其发送到显示器。缓冲区可以小于屏幕。在这种情况下,较大的区域将在多个部分中重新绘制。如果只有小区域发生变化(例如按下按钮),则只会刷新这些区域。
-
具有两个缓冲区的两个非屏幕大小的缓冲区LVGL 可以将其绘制到一个缓冲区中,而将另一个缓冲区的内容发送到后台显示。应该使用DMA或其他硬件将数据传输到显示器,让CPU同时绘制。这样,显示的渲染和刷新变得并行。与One buffer类似,如果缓冲区小于要刷新的区域,LVGL 将分块绘制显示内容。
-
两个屏幕大小的缓冲区。与两个非屏幕大小的缓冲区相比,LVGL 将始终提供整个屏幕的内容,而不仅仅是块。通过这种方式,驱动程序可以简单地将帧缓冲区的地址更改为从 LVGL 接收到的缓冲区。因此,当 MCU 具有 LCD/TFT 接口且帧缓冲区只是 RAM 中的一个位置时,此方法效果最佳。
您可以使用基准示例来衡量显示配置的性能。
显示驱动程序
一旦缓冲区初始化准备就绪,就需要初始化显示驱动程序。在最简单的情况下,只
lv_disp_drv_t需要设置以下两个字段:-
指向初始化
lv_disp_buf_t变量的缓冲区指针。 -
flush_cb一个回调函数,用于将缓冲区的内容复制到显示器的特定区域。
lv_disp_flush_ready()需要在冲洗准备好时调用。LVGL 可能会以多个块呈现屏幕,因此会flush_cb多次调用。要查看哪个是渲染的最后一块,请使用lv_disp_flush_is_last().
有一些可选的数据字段:
-
hor_res 显示器的水平分辨率。(
LV_HOR_RES_MAX默认来自lv_conf.h)。 -
ver_res 显示器的垂直分辨率。(
LV_VER_RES_MAX默认来自lv_conf.h)。 -
color_chroma_key将在镀铬键控图像上绘制为透明的颜色。
LV_COLOR_TRANSP默认情况下来自lv_conf.h)。 -
user_data驱动程序的自定义用户数据。它的类型可以在 lv_conf.h 中修改。
-
抗锯齿使用抗锯齿(边缘平滑)。
LV_ANTIALIAS默认来自lv_conf.h。 -
旋转和sw_rotate请参阅下面的旋转部分。
-
screen_transp如果
1屏幕可以具有透明或不透明样式。LV_COLOR_SCREEN_TRANSP需要在lv_conf.h 中启用。
要使用 GPU,可以使用以下回调:
-
gpu_fill_cb用颜色填充内存区域。
-
gpu_blend_cb使用不透明度混合两个内存缓冲区。
-
gpu_wait_cb如果有任何 GPU 函数返回,当 GPU 仍在 LVGL 工作时,将在需要时使用此函数,确保 GPU 渲染已准备就绪。
请注意,这些函数需要直接绘制到内存 (RAM) 而不是您的显示器。
一些其他可选的回调,使处理单色、灰度或其他非标准 RGB 显示器更容易、更优化:
-
rounder_cb四舍五入要重绘的区域的坐标。例如,2x2 像素可以转换为 2x8。如果显示控制器只能刷新具有特定高度或宽度的区域(单色显示器通常为 8 像素高度),则可以使用它。
-
set_px_cb一个自定义函数来写入显示缓冲区。如果显示器具有特殊的颜色格式,它可用于更紧凑地存储像素。(例如 1 位单色、2 位灰度等)这样使用的缓冲区
lv_disp_buf_t可以更小,以仅容纳给定区域大小所需的位数。set_px_cb不适用于显示缓冲区配置。Two screen-sized buffers -
monitor_cb一个回调函数告诉多少像素在多少时间内被刷新。
-
clean_dcache_cb用于清除与显示相关的任何缓存的回调
要设置lv_disp_drv_t变量的字段,它需要用
lv_disp_drv_init(&disp_drv). 最后lv_disp_drv_register(&disp_drv)需要调用为 LVGL 注册一个显示。放在一起看起来像这样:
lv_disp_drv_t disp_drv; /*A variable to hold the drivers. Can be local variable*/ lv_disp_drv_init(&disp_drv); /*Basic initialization*/ disp_drv.buffer = &disp_buf; /*Set an initialized buffer*/ disp_drv.flush_cb = my_flush_cb; /*Set a flush callback to draw to the display*/ lv_disp_t * disp; disp = lv_disp_drv_register(&disp_drv); /*Register the driver and save the created display objects*/这里有一些简单的回调示例:
void my_flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p) { /*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/ int32_t x, y; for(y = area->y1; y <= area->y2; y++) { for(x = area->x1; x <= area->x2; x++) { put_px(x, y, *color_p) color_p++; } } /* IMPORTANT!!! * Inform the graphics library that you are ready with the flushing*/ lv_disp_flush_ready(disp_drv); } void my_gpu_fill_cb(lv_disp_drv_t * disp_drv, lv_color_t * dest_buf, const lv_area_t * dest_area, const lv_area_t * fill_area, lv_color_t color); { /*It's an example code which should be done by your GPU*/ uint32_t x, y; dest_buf += dest_width * fill_area->y1; /*Go to the first line*/ for(y = fill_area->y1; y < fill_area->y2; y++) { for(x = fill_area->x1; x < fill_area->x2; x++) { dest_buf[x] = color; } dest_buf+=dest_width; /*Go to the next line*/ } } void my_gpu_blend_cb(lv_disp_drv_t * disp_drv, lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa) { /*It's an example code which should be done by your GPU*/ uint32_t i; for(i = 0; i < length; i++) { dest[i] = lv_color_mix(dest[i], src[i], opa); } } void my_rounder_cb(lv_disp_drv_t * disp_drv, lv_area_t * area) { /* Update the areas as needed. Can be only larger. * For example to always have lines 8 px height:*/ area->y1 = area->y1 & 0x07; area->y2 = (area->y2 & 0x07) + 8; } void my_set_px_cb(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y, lv_color_t color, lv_opa_t opa) { /* Write to the buffer as required for the display. * Write only 1-bit for monochrome displays mapped vertically:*/ buf += buf_w * (y >> 3) + x; if(lv_color_brightness(color) > 128) (*buf) |= (1 << (y % 8)); else (*buf) &= ~(1 << (y % 8)); } void my_monitor_cb(lv_disp_drv_t * disp_drv, uint32_t time, uint32_t px) { printf("%d px refreshed in %d ms\n", time, ms); } void my_clean_dcache_cb(lv_disp_drv_t * disp_drv, uint32) { /* Example for Cortex-M (CMSIS) */ SCB_CleanInvalidateDCache(); }回转
LVGL 支持以 90 度为增量旋转显示器。您可以选择是要软件轮换还是硬件轮换。
如果您选择软件旋转(
sw_rotate标志设置为 1),LVGL 将为您执行旋转。您的驱动程序可以并且应该假设屏幕宽度和高度没有改变。只需像往常一样将像素刷新到显示器即可。软件轮换在您的flush_cb回调中不需要额外的逻辑。在软件中执行轮换需要大量的开销,这就是硬件轮换也可用的原因。在这种模式下,LVGL 将绘制到缓冲区中,就好像您的屏幕现在具有反转的宽度和高度一样。您有责任自己旋转提供的像素。
初始化时显示的默认旋转可以使用
rotated标志设置。可用选项为LV_DISP_ROT_NONE,LV_DISP_ROT_90,LV_DISP_ROT_180,或LV_DISP_ROT_270。旋转值与顺时针方向旋转物理显示器的方式有关。因此,LV_DISP_ROT_90意味着您将硬件顺时针旋转 90 度,显示器逆时针旋转 90 度以进行补偿。(从 7.10.0 及更早版本升级的用户请注意:这些新的旋转枚举值与旧的 0/1 系统匹配,用于旋转 90 度,因此遗留代码应继续按预期工作。默认情况下,软件旋转也被禁用以实现兼容性.)
也可以在运行时使用API更改显示旋转。
lv_disp_set_rotation(disp, rot)支持软件轮换是一项新功能,因此根据您的配置可能存在一些故障/错误。如果您遇到问题,请在GitHub 上打开一个问题。
应用程序接口
显示驱动 HAL 接口头文件
类型定义
类型定义结构_disp_drv_t
lv_disp_drv_tHAL 要注册的显示驱动程序结构
类型定义结构_disp_t
lv_disp_t显示结构。
笔记
lv_disp_drv_t应该是结构的第一个成员。枚举
枚举
lv_disp_size_t价值观:
枚举器
LV_DISP_SIZE_SMALL枚举器
LV_DISP_SIZE_MEDIUM枚举器
LV_DISP_SIZE_LARGE枚举器
LV_DISP_SIZE_EXTRA_LARGE职能
无效
lv_disp_drv_init(lv_disp_drv_t *驱动程序)使用默认值初始化显示驱动程序。它用于在字段中具有已知值而不是内存中的垃圾。之后,您可以安全地只设置您需要的字段。
参数
驱动程序——指向要初始化的驱动程序变量的指针
void
lv_disp_buf_init( lv_disp_buf_t * disp_buf , void * buf1 , void * buf2 , uint32_t size_in_px_cnt )初始化显示缓冲区
-
-

LVGL是一个强大的图形库,用于在嵌入式设备上创建用户界面。本文档详细介绍了如何配置LVGL、设置项目、获取库、配置文件、初始化、显示界面、显示缓冲区、显示驱动程序、回转、应用程序接口、输入设备接口、时钟接口、任务处理程序、睡眠管理和操作系统中断。通过这些步骤,你可以有效地在你的嵌入式系统上构建和管理LVGL图形用户界面。
1724

被折叠的 条评论
为什么被折叠?



