LVGL(Light and Versatile Graphics Library)是一个免费的开源图形库,提供创建具有易于使用的图形元素、漂亮的视觉效果和低内存占用的嵌入式 GUI 所需的一切。
• 具有非常丰富的内置控件,像 buttons, charts, lists, sliders, images 等
• 高级图形效果:动画,反锯齿,透明度,平滑滚动
• 支持多种输入设备,像 touchpad, mouse, keyboard, encoder 等
• 支持多语言的 UTF-8 编码
• 支持多个和多种显示设备,例如同步显示在多个彩色屏或单色屏上
• 完全自定制的图形元素
• 硬件独立于任何微控制器或显示器
• 可以缩小到最小内存 (64 kB Flash, 16 kB RAM)
• 支持操作系统、外部储存和 GPU(非必须)
• 仅仅单个帧缓冲设备就可以呈现高级视觉特效
• 使用 C 编写以获得最大兼容性(兼容 C++)
• 支持 PC 模拟器
• 为加速 GUI 设计,提供教程,案例和主题,支持响应式布局
• 提供了在线和离线文档
• 基于自由和开源的 MIT 协议
获取LVGL官方驱动,例程。
https://gitcode.net/mirrors/lvgl/lvgl/-/tree/v6.0
LVGL版本众多,更新很快,初学者建议使用老版本,资料多,便于学习。
现在我们获取6.0版本。
https://gitcode.net/mirrors/lvgl/lv_examples
获取LVGL官方例程。
开始移植,先准备好一个STM32工程,新建LVGL和LVGL_APP文件夹
LVGL :存放官方驱动和例程等库文件
LVGL_APP :存放自己的程序
将下载的官方驱动文件和例程解压并存放在LVGL文件夹中,接着把 LVGL/lvgl-v6.0/lv_conf_template.h和 LVGL/lv_examples-v6.0/lv_ex_conf_templ.h
俩个配置模板文件统统拷贝到 LVGL 目录下,然后对这个 2 文件分别重命名为
lv_conf.h和 lv_ex_conf.h。接着还要在LVGL 目录下新建一个 lvgl_driver子目录,这个目录是用来放底层驱动文件的。
找到LVGL/lvglv-6.0/porting里面的
lv_port_disp_template.c, lv_port_disp_template.h,
然后将两个个文件拷贝到 LVGLlvgl_driver 目录下面,并分别重命名为
lv_port_disp.c, lv_port_disp.h,
接着我们打开 Keil 工程,点击图标,打开分组管理面板,在 Groups 栏下新建 LVGL 、LVGL_APP 、LVGL_driver,选中 LVGL 分组,接着点击 Add Files 把,LVGLlvgl-v6.0src
文件下的所有c文件全部添加。
新建LVGL_driver,将底层驱动文件添加进去。
点击图标,选择c/c++选项,将头文件目录添加,如下图所示:
打开lv_conf.h文件。
10行:0修改为1,使整个配置文件生效。
#if 1
23、24行:LV_HOR_RES_MAX 和 LV_HOR_RES_MAX,这个是告诉LVGL显示屏分辨率多大,请根据自己的屏幕大小将分辨率写入其中
LV_HOR_RES_MAX 240
LV_HOR_RES_MAX 320
32行:LV_COLOR_DEPTH 颜色深度,屏幕采用RGB565,选择16。
#define LV_COLOR_DEPTH 16
56行:LV_DPI 的值,默认值为 100,我们把他设置到 60,这个宏是用来调节界面缩 放比例的,此值越大,控件分布的就越散,控件自身的间隔也会变大
#define LV_DPI 60
72行:LV_MEM_SIZE 的大小,这个就是控制 littleVGL中所谓的动态数据堆的大小,是用来给控件的创建动态分配空间的,我们这里设置为 20KB 的大小
#define LV_MEM_SIZE (20U * 1024U)
145行:LV_USE_GPU ,我们把它设置为 0,即不使能 GPU 功能
#define LV_USE_GPU 0
148行:LV_USE_FILESYSTEM ,设置为0,即不使能文件系统 的功能
#define LV_USE_FILESYSTEM 0
234行:
LV_THEME_LIVE_UPDATE,
LV_USE_THEME_TEMPL,
LV_USE_THEME_DEFAULT,
LV_USE_THEME_ALIEN,
LV_USE_THEME_NIGHT,
LV_USE_THEME_MONO,
LV_USE_THEME_MATERIAL,
LV_USE_THEME_ZEN,
LV_USE_THEME_NEMO
这些宏都是跟littleVGL自带的主题相关的,如果要演示官方自带的例程,这些全部使能,注意,在实际项目中,我们一般最多使能一个,如果我们项目根本就用不到其自带的主题,那么我们应该把这些宏全部禁止,因为这样可以节省 flash 和 ram。现在我们要演示官方例程,可以把他们全部使能。
修改 lv_ex_conf.h 文件
9行:0修改为1 使能整个文件
#if 1
然后把下面这些宏设定为1,其余保持不变即可。
LV_EX_KEYBOARD,
LV_EX_MOUSEWHEEL,
LV_USE_TESTS,
LV_USE_TUTORIALS,
LV_USE_BENCHMARK,
LV_USE_DEMO,
LV_USE_TERMINAL
为 lVGL 提供心跳节拍
Lvgl有自己的任务系统,所以在此咱们为LVGL提供一个系统基准时间。
打开delay.c,添加#include "lvgl.h"头文件,在系统定时器中断服务函数里面添加lv_tick_inc(1);
(这里可以使用任何一个定时器的中断服务函数作为时间基准,并不是只能是系统定时器。但是要注意,中断服务函数需每1ms触发一次。)
编译 工程报错。
仔细观察错误,这一共是两种错误。
第一个错误:点击跳转,lv_conf.h文件 485行。
将头文件lvgl修改为lvgl-v6.0
第二个错:
将这5个文件,将头文件都修改为#include "lvgl.h"即可
再编译一下,就只剩下警告,没有错误了,接下来我们来解决警告。在这些警告中,仔细看其实就只有 68, 111, 550 这三种警告,我可以告诉大家,这个警告对我们项目没有任何影响的,但是强迫症患者看着就是难受,辛亏 Keil 可以通过设置,把某种警告给屏蔽掉,点击
图标,切换到 C/C++选项卡,在 Misc Controls 中填入 --diag_suppress=68 --diag_supp
ress=111 --diag_suppress=550,如下图所示.
点击确定,再次编译就没有警告了。
修改底层驱动:打开lv_port_disp.c文件
7行:0修改为1
12行:头文件修改为:#include "lv_port_disp.h"
然后就是修改
void lv_port_disp_init(void)
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
这两个函数。
第一个函数是用来给LVGL提供一个绘制对象的缓冲区。内容修改如下:
void lv_port_disp_init(void) { /* Example for 1) */ static lv_disp_buf_t disp_buf_1; static lv_color_t buf1_1[LV_HOR_RES_MAX * 10]; /*A buffer for 10 rows*/ lv_disp_buf_init(&disp_buf_1, buf1_1, NULL, LV_HOR_RES_MAX * 10); /*Initialize the display buffer*/
/*----------------------------------- * Register the display in LittlevGL *----------------------------------*/
lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/ lv_disp_drv_init(&disp_drv); /*Basic initialization*/
/*Set up the functions to access to your display*/
/*Set the resolution of the display*/ disp_drv.hor_res = LV_HOR_RES_MAX; disp_drv.ver_res = LV_VER_RES_MAX;
/*Used to copy the buffer's content to the display*/ disp_drv.flush_cb = disp_flush;
/*Set a display buffer*/ disp_drv.buffer = &disp_buf_1;
/*Finally register the driver*/ lv_disp_drv_register(&disp_drv); }
|
第二个函数是为了给LCD屏写入数据显示的函数,所以咱们调用LCD显示函数。如下:
static void disp_flush(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; int32_t y; for(y = area->y1; y <= area->y2; y++) { for(x = area->x1; x <= area->x2; x++) { /* Put a pixel to the display. For example: */ /* put_px(x, y, *color_p)*/ //这个地方需要写LCD的底层驱动函数 //可以写画点函数 LCD_Fast_DrawPoint(x,y,color_p->full); color_p++; } }
/* IMPORTANT!!! * Inform the graphics library that you are ready with the flushing*/ lv_disp_flush_ready(disp); }
|
然后修改h文件:
至此,显示底层驱动就修改好了。
LVGL移植成功。
测试:写如下函数:
void Lglv_text(void) { obj1 = lv_obj_create(lv_scr_act(),NULL);//创建对象1 lv_obj_set_pos(obj1,20,20);//设置坐标位置 lv_obj_set_size(obj1,100,100);//设置大小
obj2 = lv_obj_create(lv_scr_act(),NULL);//创建对象2 lv_obj_set_size(obj2,50,50);//设置大小 lv_obj_align(obj2,NULL,LV_ALIGN_CENTER,0,0);//设置坐标位置为屏幕中央。 } |
在主函数里面调用:
编译下载:出现两个基础的对象。
到此,LVGL移植成功
全部0条评论
快来发表一下你的评论吧 !