1、LVGL

        图形用户界面是一种人与计算机通信的界面显示格式,允许用户使用鼠标等输入设备操纵

屏幕上的图标或菜单选项,以选择命令、调用文件、启动程序或执行其它一些日常任务。通过

键盘输入文本或字符命令来完成例行任务的字符界面相比,图形用户界面有许多优点。图形用

户界面由窗口、下拉菜单、对话框及其相应的控制机制构成,在各种新式应用程序中都是标准

化的,即相同的操作总是以同样的方式来完成,在图形用户界面,用户看到和操作的都是图形

对象,应用的是计算机图形学的技术。

        在实际应用中,我们时常需要制作UI界面来实现人机交互,简单的UI可以直接编写代码,

但对于那些复杂的交互界面,自己编写UI界面可能就力不从心了。因此可使用第三方的GUI

库来设计UI界面,例如LVGL、emWin、QT等图形用户库,它们都可以设计漂亮的UI界面。

本教程主要讲解LVGL下图形用户界面的开发与使用。        

1.1 认识 LVGL

        LVGL(Light and Versatile Graphics Library)是一个免费的开源图形库,提供创建具有易

于使用的图形元素、漂亮的视觉效果和低内存占用的嵌入式 GUI。接下来我们来看一下LVGL

图形用户库的主要特征有哪些:

1. 强大的构建块:按钮、图表、列表、滑块、图像等部件。

2. 具有高级图形属性:具有动画、抗锯齿、不透明度、平滑滚动的高级图形。

3. 支持各种输入设备:如触摸、鼠标、键盘、编码器。

4. 支持多语言:UTF-8 编码。

5. 支持多显示器:它可以同时使用多个 TFT或者单色显示器。

6. 支持多种样式属性:它具有类 CSS 样式的完全可定制的图形元素。

7. 独立于硬件之外:它与任何微控制器或显示器一起使用。

8. 可扩展性:它能够以小内存运行(最低64 kB 闪存,16 kB RAM的MCU)。

9. 支持操作系统、外部存储器和 GPU(不是必需的)。

10. 具有高级图形效果:可进行单帧缓冲区操作。

11. 纯C编写: C 语言编写以获得最大的兼容性。

从上述特征可知:LVGL是一款具有丰富的部件,具备高级图形特性,支持多种输入设备,

多国语言和独立于硬件之外等免费的开源图形库。LVGL官方地址为:https://lvgl.io/,该网页

主要包含用户文档以及图片和字体转换器,该网页打开后如图1.1.1所示:

        上图中的“Github”图标可点击进入下载LVGL相关源码的网页;上图中 的“Docs”图标

可点击进入LVGL用户文档,该文档是纯英文编写的,主要讲解LVGL移植方式和各个部件的

使用;上图右上角的“Tools”选项主要提供用户图片和字库在线转换器,这些转换器是以某

种规则把目标文件转换成嵌入式可读取的文件。

2、LVGL无操作系统移植

在上一个章节中,我们已经了解LVGL移植需求以及LVGL图形库下载路径。本章主要讲

解裸机移植LVGL到正点原子STM32开发板上。首先声明一下,本教程适用于正点原子的所

有STM32 开发板,支持正点原子的全系列显示屏,当然不同的开发板对显示屏型号的支持力

度大小可能会不同,这个会在相应开发板的配套例程代码中进行说明,为了方便读者,本教程

中的图片和素材都是通用的,如有区别,笔者将会在教程中以表格的方式指出。

本章分为如下几个部分讲解:

2.1 移植准备工作

2.2 向工程添加文件

2.3 修改工程文件

2.4 移植官方例程

2.5下载验证

2.1 移植准备工作

        在移植LVGL之前,用户必须在裸机例程中找到一个移植基础例程,笔者建议使用正点原

子 STM32开发板的裸机例程中的内存管理实验(注意:该实验必须包含 LCD显示驱动以及

touch触摸驱动文件),有学过正点原子STM32开发板的资料的用户都知道,内存管理实验的

内存算法是正点原子独有的一套算法,该算法主要管理内部SRAM以及外部SRAM的内存。

因为LVGL库内含自己内存管理算法,该管理算法的管理内存是由用户分配给它的,所以用户

分配内存方式有两种,一种是内部SRAM分配方式,而另一种是外部SRAM分配方式。下面

我们开始讲解移植准备工作的流程,如下所示:

1. 准备LVGL源码

        LVGL源码可从LVGL官方GitHub网址(https://github.com/lvgl/lvgl/)下载。当然我们也可

以在正点原子光盘资料下获取,该获取路径为:“6.软件资料→14.LVGL学习资料→lvgl-

maser.zip”。该压缩包解压后得到下图的文件和文件夹。

3、代码附录

#include <stdio.h>

#include <inttypes.h>

#include "sdkconfig.h"

#include "freertos/FreeRTOS.h"

#include "freertos/task.h"

#include "esp_chip_info.h"

#include "esp_flash.h"

#include "esp_system.h"

#include"LCD.h"

#include"tig.h"

#include <Timer.h>

#include "demos/lv_demos.h"

static void event_handler(lv_event_t * e)

{

 }

void lv_example_demo(void)

{

     lv_obj_t * label;

    label = lv_label_create(lv_scr_act());

    lv_label_set_text(label, "login interface");

    lv_obj_set_width(label, 240);

    lv_obj_set_height(label, 30);

    lv_obj_set_x(label, 20);

    lv_obj_set_y(label, 0);

    lv_obj_t * btn1 = lv_button_create(lv_screen_active());

    lv_obj_add_event_cb(btn1, event_handler, LV_EVENT_ALL, NULL);

    //lv_obj_align(btn1, LV_ALIGN_CENTER, 0, -40);

    lv_obj_remove_flag(btn1, LV_OBJ_FLAG_PRESS_LOCK);

    lv_obj_set_width(btn1,120);

    lv_obj_set_height(btn1,24);

    lv_obj_set_x(btn1,20);

    lv_obj_set_y(btn1,150);

    label = lv_label_create(btn1);

    lv_label_set_text(label, "login");

    lv_obj_center(label);

    lv_obj_t * btn2 = lv_button_create(lv_screen_active());

    lv_obj_add_event_cb(btn2, event_handler, LV_EVENT_ALL, NULL);

    lv_obj_set_width(btn2,120);

    lv_obj_set_height(btn2,24);

    lv_obj_set_x(btn2,150);

    lv_obj_set_y(btn2,150);


 

    label = lv_label_create(btn2);

    lv_label_set_text(label, "Toggle");

    lv_obj_center(label);

    // //复选框

   

    lv_obj_t * cb;

    cb = lv_checkbox_create(lv_screen_active());

    lv_checkbox_set_text(cb, "Apple");

    lv_obj_add_event_cb(cb, event_handler, LV_EVENT_ALL, NULL);

    lv_obj_update_layout(cb);

    lv_obj_set_x(cb, 40);

    lv_obj_set_y(cb, 120);

    lv_obj_t * cb1;

    cb1 = lv_checkbox_create(lv_screen_active());

    lv_checkbox_set_text(cb1, "Banana");

    lv_obj_add_state(cb1, LV_STATE_CHECKED);

    lv_obj_add_event_cb(cb1, event_handler, LV_EVENT_ALL, NULL);

    lv_obj_update_layout(cb1);

    lv_obj_set_x(cb1, 160);

    lv_obj_set_y(cb1, 120);


 

    lv_obj_t * cb2;

    cb2 = lv_checkbox_create(lv_screen_active());

    lv_checkbox_set_text(cb2, "budianbugeidenglu.com");

    lv_obj_add_state(cb2, LV_STATE_CHECKED);

    lv_obj_add_event_cb(cb2, event_handler, LV_EVENT_ALL, NULL);

    lv_obj_update_layout(cb2);

    lv_obj_set_x(cb2, 40);

    lv_obj_set_y(cb2, 200);

    // 创建文本输入区域

    lv_obj_t *textarea = lv_textarea_create(lv_scr_act());

    lv_textarea_set_placeholder_text(textarea, "QQ");

    lv_textarea_set_one_line(textarea, true);  // 单行模式

    lv_obj_set_size(textarea, 250, 40);

    lv_obj_set_x(textarea,20);

    lv_obj_set_y(textarea,20);

    // 创建文本输入区域

    lv_obj_t *textarea1 = lv_textarea_create(lv_scr_act());

    lv_textarea_set_placeholder_text(textarea1, "mima");

    lv_textarea_set_one_line(textarea1, true);  // 单行模式

    lv_obj_set_size(textarea1, 250, 40);

    lv_obj_set_x(textarea1,20);

    lv_obj_set_y(textarea1,70);
 

}

void app_main(void)

{

   

    bsp_i2c_init();

    pca9557_init();

    bsp_lvgl_start();

    lv_example_demo();

    while(1){

       

        vTaskDelay(10);

    }

}

4、成果展示

5、心得体会

        第四天的学习也收获满满,认真跟随老师的步伐,成就感满满,也自己简单调试更改代码都很成功,明天继续学习。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐