littleVGL开源图形库的主要特性与移植过程

描述

 

1. littleVGL 介绍

 

LVGL(Light and Versatile Graphics Library)是一个免费的开源图形库,提供创建具有易于使用的图形元素、漂亮的视觉效果和低内存占用的嵌入式 GUI 所需的一切。

 

1.1 littleVGL 的主要特性如下:

具有非常丰富的内置控件, buttons, charts, lists, sliders, images

高级图形效果:动画,反锯齿,透明度,平滑滚动

支持多种输入设备, touchpad, mouse, keyboard, encoder

支持多语言的 UTF-8 编码

支持多个和多种显示设备,例如同步显示在多个彩色屏或单色屏上

完全自定制的图形元素

硬件独立于任何微控制器或显示器

可以缩小到最小内存 (64 kB Flash, 16 kB RAM)

支持操作系统、外部储存和 GPU(非必须)

仅仅单个帧缓冲设备就可以呈现高级视觉特效

使用 C 编写以获得最大兼容性(兼容 C++)

支持 PC 模拟器

为加速 GUI 设计,提供教程,案例和主题,支持响应式布局

提供了在线和离线文档

基于自由和开源的 MIT 协议

 

 

 

 

 

 

1.2 LVGL移植过程

获取LVGL官方驱动,例程。

https://gitcode.net/mirrors/lvgl/lvgl/-/tree/v6.0

LVGL版本众多,更新很快,初学者建议使用老版本,资料多,便于学习。

现在我们获取6.0版本。

图形库

 

 

 

 

 

 

https://gitcode.net/mirrors/lvgl/lv_examples

获取LVGL官方例程。

图形库

 

 

 

 

开始移植,先准备好一个STM32工程,新建LVGLLVGL_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移植成功

 

  审核编辑:汤梓红
 

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

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分