嵌入式图形界面库lvgl使用详解

前言

本文相当一个快速入门的lvgl学习教程,主要记录了lvgl在vscode开发环境的配置,以及相关的环境配置,最后通过实例熟悉lvgl的使用。
下面主要参考了lvgl中文文档,还有一个优秀博主的系列博文

(一)lvgl ubuntu环境vscode模拟器安装配置

一开始接触lvgl时,lvgl版本已经更新到了8.0了,但网上的教程大多数时7.11的,在配置vscode lvgl模拟器开发环境lv_sim_vscode_sdl的时候遇到了些麻烦。

1.首先,github在国内访问速度极慢,直接git clone几乎失效,
2.lv_examples是对应lvgl 7.11的,当前lvgl 8.0对应的lv_examples已经改名为了lv_demos,git clone下来的也是lv_demos.
3.lv_drivers,lvgl需要自己现在配置

我把配置好的lv_sim_vscode_sdl的项目配置好后,直接发布在到了gitee上。
下面是安装过程。

//安装sdl
sudo apt-get update && sudo apt-get install -y build-essential libsdl2-dev

//git clone 项目
git clone https://gitee.com/lingcb/lv_sim_vscode_sdl-7.11.0.git

当环境安装了vscode时,双击文件simulator.code-workspace,打开项目。若打不开,直接使用vscode打开文件夹。
在这里插入图片描述

(二)lvgl lv_conf.h环境配置

lv_conf.h文件里可以设置屏幕的大小
下面的具体变量

#define LV_HOR_RES_MAX          (240)
#define LV_VER_RES_MAX          (320)

需要注意的点是,若项目编译运行了,生成了build文件夹,需要删除 build文件夹,再重新按F5重新运行,在lv_conf.h上的配置才生效。

之后的运行几个经典的例子,可以参考这篇博文后面部分。

(三)lvgl 控件使用的几个例子

这里给几个使用的例子。

(1)bar.h

创建一个文件“bar.h”,在上面的项目里的“main.c”,导入下面的bar.h代码。根据图片的位置上添加直接运行,便可。后续的几个控件的运行,基本差不多。

//参考:http://lvgl.100ask.org/7.11/documentation/04_widgets/03_bar.html
//导入lvgl载入h文件
#include "../lvgl/lvgl.h"
//定义控件,及相关事件
static void bar()
{
    lv_obj_t * bar1 = lv_bar_create(lv_scr_act(), NULL);
    lv_obj_set_size(bar1, 200, 20);
    lv_obj_align(bar1, NULL, LV_ALIGN_CENTER, 0, 0);
    lv_bar_set_anim_time(bar1, 20000);
    lv_bar_set_value(bar1, 100, LV_ANIM_ON);
}

在这里插入图片描述

(2)button.h

//参考:http://lvgl.100ask.org/7.11/documentation/04_widgets/04_btn.html
//导入lvgl载入h文件
#include <stdio.h>
#include "../lvgl/lvgl.h"

//定义控件,及相关事件
static void event_handler(lv_obj_t * obj, lv_event_t event)
     {
             if(event == LV_EVENT_CLICKED) {
                     printf("Clicked\n");
             }
            else if(event == LV_EVENT_VALUE_CHANGED) {
                    printf("Toggled\n");
            }
    }

static void button()
{
    lv_obj_t * label;
    lv_obj_t * btn1 = lv_btn_create(lv_scr_act(), NULL);
     lv_obj_set_event_cb(btn1, event_handler);
    lv_obj_align(btn1, NULL, LV_ALIGN_CENTER, 0, -40);
            
    label = lv_label_create(btn1, NULL);
    lv_label_set_text(label, "Button");

     lv_obj_t * btn2 = lv_btn_create(lv_scr_act(), NULL);
    lv_obj_set_event_cb(btn2, event_handler);
    lv_obj_align(btn2, NULL, LV_ALIGN_CENTER, 0, 40);
    lv_btn_set_checkable(btn2, true);
    lv_btn_toggle(btn2);
    lv_btn_set_fit2(btn2, LV_FIT_NONE, LV_FIT_TIGHT);

    label = lv_label_create(btn2, NULL);
    lv_label_set_text(label, "Toggled");    
}

(3)image.h

//参考:http://lvgl.100ask.org/7.11/documentation/04_widgets/14_img.html
//导入lvgl载入h文件
#include "../lvgl/lvgl.h"

//定义控件,及相关事件
#define SLIDER_WIDTH 20
static void create_sliders(void);
static void slider_event_cb(lv_obj_t * slider, lv_event_t event);
 
static lv_obj_t * red_slider, * green_slider, * blue_slider, * intense_slider;
static lv_obj_t * img1;
LV_IMG_DECLARE(img_cogwheel_argb);

static void slider_event_cb(lv_obj_t * slider, lv_event_t event)
    {
        if(event == LV_EVENT_VALUE_CHANGED) {
                    /* Recolor the image based on the sliders' values */
                    lv_color_t color  = lv_color_make(lv_slider_get_value(red_slider), lv_slider_get_value(green_slider), lv_slider_get_value(blue_slider));
                    lv_opa_t intense = lv_slider_get_value(intense_slider);
                    lv_obj_set_style_local_image_recolor_opa(img1, LV_IMG_PART_MAIN, LV_STATE_DEFAULT, intense);
                    lv_obj_set_style_local_image_recolor(img1, LV_IMG_PART_MAIN, LV_STATE_DEFAULT, color);
            }
    }

    static void create_sliders(void)
    {
            /* Create a set of RGB sliders */
            /* Use the red one as a base for all the settings */
            red_slider = lv_slider_create(lv_scr_act(), NULL);
            lv_slider_set_range(red_slider, 0, 255);
            lv_obj_set_size(red_slider, SLIDER_WIDTH, 200); /* Be sure it's a vertical slider */
            lv_obj_set_style_local_bg_color(red_slider, LV_SLIDER_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_RED);
            lv_obj_set_event_cb(red_slider, slider_event_cb);
            /* Copy it for the other three sliders */
            green_slider = lv_slider_create(lv_scr_act(), red_slider);
            lv_obj_set_style_local_bg_color(green_slider, LV_SLIDER_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_LIME);

            blue_slider = lv_slider_create(lv_scr_act(), red_slider);
            lv_obj_set_style_local_bg_color(blue_slider, LV_SLIDER_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_BLUE);

            intense_slider = lv_slider_create(lv_scr_act(), red_slider);
            lv_obj_set_style_local_bg_color(intense_slider, LV_SLIDER_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_GRAY);
            lv_slider_set_value(intense_slider, 255, LV_ANIM_OFF);

            lv_obj_align(red_slider, NULL, LV_ALIGN_IN_LEFT_MID, 20, 0);
            lv_obj_align(green_slider, red_slider, LV_ALIGN_OUT_RIGHT_MID, 20, 0);
            lv_obj_align(blue_slider, green_slider, LV_ALIGN_OUT_RIGHT_MID, 20, 0);
            lv_obj_align(intense_slider, blue_slider, LV_ALIGN_OUT_RIGHT_MID, 20, 0);
    }

static void image(void){
    create_sliders();
    /* Now create the actual image */
    img1 = lv_img_create(lv_scr_act(), NULL);
    lv_img_set_src(img1, &img_cogwheel_argb);
    lv_obj_align(img1, NULL, LV_ALIGN_IN_RIGHT_MID, -20, 0);
}

(4)label.h

//参考:http://lvgl.100ask.org/7.11/documentation/04_widgets/17_label.html
//导入lvgl载入h文件
#include "../lvgl/lvgl.h"

//定义控件,及相关事件
static void label()
{
    lv_obj_t * label1 = lv_label_create(lv_scr_act(), NULL);
    lv_label_set_long_mode(label1, LV_LABEL_LONG_BREAK);     /*Break the long lines*/
    lv_label_set_recolor(label1, true);                      /*Enable re-coloring by commands in the text*/
    lv_label_set_align(label1, LV_LABEL_ALIGN_CENTER);       /*Center aligned lines*/
    lv_label_set_text(label1, "#0000ff Re-color# #ff00ff words# #ff0000 of a# label "
                                                                "and  wrap long text automatically.");
    lv_obj_set_width(label1, 150);
    lv_obj_align(label1, NULL, LV_ALIGN_CENTER, 0, -30);

    lv_obj_t * label2 = lv_label_create(lv_scr_act(), NULL);
    lv_label_set_long_mode(label2, LV_LABEL_LONG_SROLL_CIRC);     /*Circular scroll*/
    lv_obj_set_width(label2, 150);
    lv_label_set_text(label2, "It is a circularly scrolling text. ");
    lv_obj_align(label2, NULL, LV_ALIGN_CENTER, 0, 30); 
}

(5)switch.h

//参考:http://lvgl.100ask.org/7.11/documentation/04_widgets/29_switch.html
//导入lvgl载入h文件
#include <stdio.h>
#include "../lvgl/lvgl.h"

//定义控件,及相关事件
static void switch_event_handler(lv_obj_t * obj, lv_event_t event)
     {
             if(event == LV_EVENT_VALUE_CHANGED) {
                     printf("State: %s\n", lv_switch_get_state(obj) ? "On" : "Off");
             }
    }
static void _switch()
{
    lv_obj_t *sw1 = lv_switch_create(lv_scr_act(), NULL);
    lv_obj_align(sw1, NULL, LV_ALIGN_CENTER, 0, -50);
    lv_obj_set_event_cb(sw1, switch_event_handler);
    /*Copy the first switch and turn it ON*/
    lv_obj_t *sw2 = lv_switch_create(lv_scr_act(), sw1);
     lv_switch_on(sw2, LV_ANIM_ON);
    lv_obj_align(sw2, NULL, LV_ALIGN_CENTER, 0, 50);
}

(四)lvgl 任务(task)使用

lvgl task添加后,可以自动定时运行。
使用方法依旧如上。

//参考:https://blog.csdn.net/weixin_41572450/article/details/111546117
//导入lvgl载入h文件
#include "../lvgl/lvgl.h"

//basic variables
uint8_t test_data = 0;
lv_obj_t * label1;

//define label
static void task_label()
{
    label1 = lv_label_create(lv_scr_act(), NULL);
    lv_label_set_long_mode(label1, LV_LABEL_LONG_BREAK);     /*Break the long lines*/
    lv_label_set_align(label1, LV_LABEL_ALIGN_CENTER);                /*Center aligned lines*/
    lv_label_set_text(label1, "Hello World!");
    lv_obj_set_width(label1, 150);
    lv_obj_align(label1, NULL, LV_ALIGN_CENTER, 0, -30);
}

//callback function
static void task_cb(lv_task_t* task)
{
    uint8_t *user_data = (uint8_t*)task->user_data;
    (*user_data)++;
    lv_label_set_text_fmt(label1, "Value: %d", *user_data);
}

//creat a task
void task(void)
{
     task_label();
    lv_task_t * t = lv_task_create(task_cb,1000,LV_TASK_PRIO_MID, &test_data);
}

(五)lvgl 图片(使用)

lvgl 可以通过C array导入图片显示,下面是一个使用图片的例子。imgs/backgroud.h lvgl官方提供的在线转换器转换而来,当图片上传,转换的结果格式是.c的,下载来后修改格式为.h就可以直接导入了。需要注意一点:当上传图片后,会出现File name(s)这选项,里面提前命名好,后面的引用会直接用到。

//参考:https://blog.csdn.net/weixin_41572450/article/details/111546117
//导入lvgl载入h文件
#include "../lvgl/lvgl.h"
#include "imgs/backgroud.h"

//basic variables
uint8_t pos_data = 0;
lv_obj_t * pos_label;

//define label
static void posxyz_label()
{
    //setting backgroud
    //LV_IMG_DECLARE(backgroud_map);
    img1 = lv_img_create(lv_scr_act(), NULL);
    lv_img_set_auto_size(img1, true);
    lv_img_set_src(img1, &backgroud);
    lv_obj_align(img1, NULL, LV_ALIGN_IN_RIGHT_MID, 0, 0);
    //setting label
    pos_label = lv_label_create(lv_scr_act(), NULL);
    lv_label_set_long_mode(pos_label, LV_LABEL_LONG_BREAK);     /*Break the long lines*/
    lv_label_set_align(pos_label, LV_LABEL_ALIGN_CENTER);                /*Center aligned lines*/
     // set font size
    static lv_style_t font_style;
	lv_style_init(&font_style);
	lv_style_set_text_font(&font_style, LV_STATE_DEFAULT, &lv_font_montserrat_30);
	lv_obj_add_style(pos_label,LV_LABEL_PART_MAIN, &font_style);
    //setting basic
    lv_label_set_text(pos_label, "\nStart");
    lv_obj_set_width(pos_label, 150);
    lv_obj_align(pos_label, NULL, LV_ALIGN_CENTER, 0, -30);

}

//callback function
static void pos_task_cb(lv_task_t* task)
{
    uint8_t *user_data = (uint8_t*)task->user_data;
    (*user_data)++;
    uint8_t x;
    uint8_t y;
    uint8_t z;

    if (*user_data>=9999){
        *user_data=0;
    }
    
    x =  ((*user_data)%1000)/100;
    y =  ((*user_data)%100)/10;
    z =  ((*user_data)%10);

    lv_label_set_text_fmt(pos_label, "\n%d,%d,%d", x,y,z);
}

//creat a task
void pos_task(void)
{
     posxyz_label();
    lv_task_t * t = lv_task_create(pos_task_cb,100,LV_TASK_PRIO_MID, &pos_data);
}


  • 8
    点赞
  • 82
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 嵌入式系统中的是一组预编译的代码,可用于提供常见的功能和算法。它们可以帮助嵌入式系统的开发人员提高开发效率和可靠性。以下是嵌入式系统中使用的简要说明: 1. 确认嵌入式系统所需的:在开发嵌入式系统之前,需要确定哪些可以用于系统。这通常基于开发人员对系统所需功能的了解。 2. 获取:获取所需的有几种方式,可以从互联网下载,也可以从供应商获得。 3. 配置:在使用之前,需要配置以适合嵌入式系统。这通常涉及到编译以生成可在目标嵌入式系统上运行的二进制文件。 4. 链接:在将程序编译成可执行文件时,需要将所需的链接到程序中。这通常可以通过在编译命令中包含文件的名称来实现。 5. 调用函数:一旦已经链接到程序中,开发人员就可以调用函数来实现所需的功能。这通常涉及包含头文件并使用函数名称调用函数。 6. 测试:在使用之前,需要测试以确保它能够在嵌入式系统上正确工作。这可以通过编写测试程序来完成,该程序使用函数来测试的功能。 总之,嵌入式系统中的可以提供常见的功能和算法,以提高开发效率和可靠性。它们可以通过获取,配置,链接,调用函数和测试使用。 ### 回答2: 嵌入式系统中是一种重要的软件工具,用于简化开发人员在嵌入式系统中的编程工作。是一组预先编写好的代码模块,包含了常见和复杂的功能函数,开发人员可以通过调用这些函数来实现特定的功能,提高开发效率并减少重复编写代码的工作量。 嵌入式系统中的主要有两种类型:系统和应用。系统主要由操作系统提供,包括底层驱动和操作系统接口函数等,用于管理硬件资源、操作系统和外设的各种功能。而应用则是由开发人员根据项目需求编写的,用于实现具体的应用功能。应用一般包含与项目紧密相关的功能模块,如通信协议、算法、图形界面等。 在嵌入式系统中使用的过程中,开发人员首先需要了解所需要的函数的接口和功能,然后将文件添加到项目中,并在代码中引用函数。通过调用函数,开发人员可以直接使用中封装好的功能,而无需了解其内部实现细节。 使用的好处主要有以下几点。首先,使用可以大大简化开发工作,因为开发人员不需要重复编写已有的功能,只需调用函数即可。其次,的代码通常经过优化和测试,具有较高的质量和稳定性,可以提高系统的可靠性。此外,还可以提供标准化的接口,方便代码的重用和维护。 然而,使用也存在一些问题。首先,选择合适的对于项目的成功与否至关重要,需要根据项目需求、性能要求和可用资源来进行评估和选择。此外,的版本更新也需要注意,更新后可能会引入新的问题或不兼容性。 总结来说,嵌入式系统中的是一种重要的软件工具,通过使用可以提高开发效率,减少开发工作量,并提高系统的可靠性。但是在使用过程中需要慎重选择,并留意的版本更新。 ### 回答3: 嵌入式系统中的是预先编写好的一组函数集合,可以供开发者在应用程序中直接调用。这些包含一系列已经实现好的常用功能,从而可以大大简化嵌入式系统开发的过程。嵌入式系统中的可以分为两种类型:系统和应用。 系统是由操作系统或核心团队编写的,在嵌入式系统中起到管理硬件和提供基本功能的作用。它们通常包括设备驱动程序,操作系统API,中断处理函数等。系统可以使开发者无需关心底层硬件细节,只需通过调用相应的函数即可实现对硬件的控制和操作。 应用则由开发者编写,用于实现特定应用的功能。这些包含了一系列的函数,可以帮助开发者快速编写应用程序。例如,如果要开发一个嵌入式系统的温度监测应用,可以使用传感器驱动来读取传感器数据,然后使用数据处理来计算温度值,最后使用显示将温度值显示在屏幕上。通过使用这些应用,开发者无需从零开始编写所有的功能代码,大大提高了开发效率。 对于嵌入式系统开发者来说,使用具有很多优点。首先,它们可以提供已经经过验证的功能和算法,保证了系统的可靠性和稳定性。其次,通过使用,开发者可以节省大量的时间和精力,减少代码量,降低了出错的可能性。此外,使用还可以提高代码的可维护性和可重用性,方便开发者进行系统的更改和升级。 总结起来,嵌入式系统中的是一种非常重要的开发工具,可以帮助开发者更加高效地编写代码并实现各种功能。通过使用,开发者可以快速搭建系统框架,提高开发效率和系统的可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值