编译lvgl(V8.4.0)源代码为.lib文件并验证

news2025/1/12 18:43:08

目录

概述

1.  软硬件信息

1.1 开发版硬件

1.2 软件版本信息

2 编译LVGL为.lib

2.1 准备工作

 2.2 编译.lib

3 验证.lib

3.1 Keil中加载.lib

3.2 Keil配置头文件路径

 3.3 编译代码

4 应用程序

4.1 主函数中初始化接口

4.2 LVGL demo测试

4.2.1 编写测试代码

4.2.2 编译和测试


源代码下载地址:

应用lvgl的.lib的一个范例(stm32-f407-lvgl-lib-ui-proj)资源-CSDN文库

概述

本文主要介绍如何将lvgl的源文件转化为.lib文件,以及大简化加载lvgl源代码的繁琐步骤。随着lvgl的版本升级越来越高,其源代码也越来越多,项目中加载这些文件也是一个繁琐的任务,本文写作的目的就是为了简化这一操作。使用.LIB文件的方式,极大的简化添加源代码的过程更便于平台的移植。

未使用.lib库的lvgl项目文件结构

使用lib库后的项目文件结构:

1.  软硬件信息

1.1 开发版硬件

软硬件信息版本信息
STM32 MCUSTM32F407IGTx
KeilMDK ARM 5.38
STM32CubeMXV6.8.1
调试工具:st-linkST-LINK/V2-1

1.2 软件版本信息

软件信息版本信息
STM32 HALSTM32Cube_FW_F4_V1.27.1
LVGLV8.4.0

2 编译LVGL为.lib

2.1 准备工作

在将lvgl库编译为.lib库之前,必须保证lvgl已经被正确的移植到板卡中中,且设计一个简单的UI,保证其能正常工作。

笔者使用lvgl源代码版本为V8.4.0,其在Keil IED中的代码结构如下:

 2.2 编译.lib

使用.lib文件能极大的简化源文件的加载过程,在实际的项目开发过程中,程序员很少会去更改第三方的库函数。所以,为了简化代码结构,会把第三方的库,编译生成一个.LIB文件。其编译步骤如下:

1)disable 非第三方的源文件

该项目的目的是把lvgl的源代码打包称为一个.LIB文件。那么非lvgl源代码相关的文件就没有必要编译到该.lib中。

在Keil IED上右键点击源代码文件夹,不要勾选如下两个checkbox。依次操作其他源文件目录。

完成操作后,可以看见如下架构: 

2)编译lvgl库文件

完成以上配置之后,此时就可以编译 工程代码。编译成功后会看见如下信息:

3 验证.lib

3.1 Keil中加载.lib

由于lvgl的库文件和LCD显示和touch功能密切相关,在添加.LIB之前,必须保证LCD显示功能和Touch功能都能正常工作。

1)下载lvgl源代码v8.4.0,将如下四个目录或者文件放在GUI/lvgl目录下

把lvgl源代码放在工程目录下的原因:

上文已经将lvgl的.c文件编译成了.lib文件,项目中在调用.lib中的函数时,需要.h文件进行索引。而这些.h文件被放在lvgl的源文件下多个目录中,项目中只需添加头文件的路径即可,无需添加.c文件

2) 准备.lib文件

将.lib文件放在GUI/lvgl目录下

 3) Keil中添加文件

GUI/lvgl: 该目录下放置lvgl.lib文件

GUI/lvgl_port: 该目录下放置和lvgl相关的接口函数文件,包括LCD接口函数,触摸屏接口

3.2 Keil配置头文件路径

在Keil中,需要配置如下几个头文件的路径

 3.3 编译代码

完成以上配置之后,就可以编译代码,编译结果如下:

4 应用程序

4.1 主函数中初始化接口

1)在main.c文件中引用lvgl相关的头文件

2)初始化lvgl相关的接口

代码116行: 初始化lvgl

代码118行: 初始化lvgl-lcd相关接口

代码120行: 初始化lvgl-touch相关接口

注意点: 先初始化lcd display, 在初始化touch

代码129行: 调用lvgl tick

代码129行: 调用lvgl task函数

3)完成以上函数之后,重新编译代码,如果代码编译成功,就可以设计UI了

4.2 LVGL demo测试

4.2.1 编写测试代码

创建一个GUI/demo文件夹,在该文件夹中创建如下如下文件

编写如下测试代码 

/* USER CODE BEGIN Header */
/**
******************************************************************************
* File Name            : lv_mainstart.c
* Description          : lvgl demo
* LVGL ver             : V8.4.0
* 
******************************************************************************
* @attention
*
* Copyright (c) 2024~2029 mingfei.tang
* All rights reserved.
*
*************************************************************************
*/
/* USER CODE END Header */
#include "demo.h"

#include "lvgl.h"
#include <stdio.h>

#define scr_act_width() lv_obj_get_width(lv_scr_act())
#define scr_act_height() lv_obj_get_height(lv_scr_act())

static lv_obj_t *switch_cool;
static lv_obj_t *switch_heat;
static lv_obj_t *switch_dry;
static const lv_font_t *font;


static void switch_event_cb(lv_event_t *e)
{
    lv_obj_t *target = lv_event_get_target(e);

    if(target == switch_cool) 
    {
        if(lv_obj_has_state(switch_cool, LV_STATE_CHECKED))
        {
            lv_obj_clear_state(switch_heat, LV_STATE_CHECKED);
        }
    }
    else if(target == switch_heat) 
    {
        if(lv_obj_has_state(switch_heat, LV_STATE_CHECKED))
        {
            lv_obj_clear_state(switch_cool, LV_STATE_CHECKED);
        }
    }

}


static void lv_example_label(void)
{

    if (scr_act_width() <= 320)
    {
        font = &lv_font_montserrat_14;
    }
    else if (scr_act_width() <= 480)
    {
        font = &lv_font_montserrat_24;
    }
    else
    {
        font = &lv_font_montserrat_26;
    }
    lv_obj_t *label = lv_label_create(lv_scr_act()); 
    lv_label_set_text(label, "Control  Center");        
    lv_obj_set_style_text_font(label, font, LV_STATE_DEFAULT); 
    lv_obj_align(label, LV_ALIGN_CENTER, 0, -scr_act_height() / 3 ); 
}


static void lv_example_switch1(void)
{

    lv_obj_t *obj_cool = lv_obj_create(lv_scr_act());
    lv_obj_set_size(obj_cool,scr_act_height() / 3, scr_act_height() / 3 );
    lv_obj_align(obj_cool, LV_ALIGN_CENTER, -scr_act_width() / 4, 0 );


    lv_obj_t *label_cool = lv_label_create(obj_cool);
    lv_label_set_text(label_cool, "Cool");                 
    lv_obj_set_style_text_font(label_cool, font, LV_STATE_DEFAULT);
    lv_obj_align(label_cool, LV_ALIGN_CENTER, 0, -scr_act_height() / 16 );


    switch_cool = lv_switch_create(obj_cool); 
    lv_obj_set_size(switch_cool,scr_act_height() / 6, scr_act_height() / 12 );
    lv_obj_align(switch_cool, LV_ALIGN_CENTER, 0, scr_act_height() / 16 );
    lv_obj_add_event_cb(switch_cool, switch_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
}


static void lv_example_switch2(void)
{
    lv_obj_t *obj_heat = lv_obj_create(lv_scr_act());
    lv_obj_set_size(obj_heat,scr_act_height() / 3, scr_act_height() / 3 );
    lv_obj_align(obj_heat, LV_ALIGN_CENTER, 0, 0 );


    lv_obj_t *label_heat = lv_label_create(obj_heat);
    lv_label_set_text(label_heat, "Heat");
    lv_obj_set_style_text_font(label_heat, font, LV_STATE_DEFAULT);
    lv_obj_align(label_heat, LV_ALIGN_CENTER, 0, -scr_act_height() / 16 );


    switch_heat = lv_switch_create(obj_heat);
    lv_obj_set_size(switch_heat,scr_act_height() / 6, scr_act_height() / 12 );
    lv_obj_align(switch_heat, LV_ALIGN_CENTER, 0, scr_act_height() / 16 );
    lv_obj_add_event_cb(switch_heat, switch_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
}


static void lv_example_switch3(void)
{

    lv_obj_t *obj_dry = lv_obj_create(lv_scr_act());
    lv_obj_set_size(obj_dry,scr_act_height() / 3, scr_act_height() / 3 );
    lv_obj_align(obj_dry, LV_ALIGN_CENTER, scr_act_width() / 4, 0 );

    lv_obj_t *label_dry = lv_label_create(obj_dry);
    lv_label_set_text(label_dry, "Dry");
    lv_obj_set_style_text_font(label_dry, font, LV_STATE_DEFAULT);
    lv_obj_align(label_dry, LV_ALIGN_CENTER, 0, -scr_act_height() / 16 );


    switch_dry = lv_switch_create(obj_dry);
    lv_obj_set_size(switch_dry,scr_act_height() / 6, scr_act_height() / 12 );
    lv_obj_align(switch_dry, LV_ALIGN_CENTER, 0, scr_act_height() / 16 );
    lv_obj_add_state(switch_dry, LV_STATE_CHECKED|LV_STATE_DISABLED);
}


void lv_mainstart(void)
{
    lv_example_label(); 
    lv_example_switch1(); 
    lv_example_switch2();
    lv_example_switch3();
}

4.2.2 编译和测试

编写完成以上代码后,在main函数中调用:lv_mainstart()

编译代码,下载文件至板卡中,运行结果如下:

 触动switch button

触动之后UI的变化

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1895970.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

字符串和正则表达式踩坑

// 中石化加油卡号格式&#xff1a;以 100011 开头共19位public static final String ZHONGSHIYOU_OIL_CARD_PATTERN "^100011\\d{13}$";// 中石油加油卡号格式&#xff1a;以90、95、70开头共16位public static final String ZHONGYOU_OIL_CARD_PATTERN "^(9…

房屋租赁管理小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;中介管理&#xff0c;房屋信息管理&#xff0c;房屋类型管理&#xff0c;租房订单管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;房屋信息&#xff0c;我的 开发系统…

植物大战僵尸融合嫁接版 MAC 版本下载安装详细教程

继植物大战僵尸杂交版火了之后&#xff0c;PVZ改版可谓是百花齐放&#xff0c;最近又有一个非常好玩的模式被开发出来了&#xff0c;他们称为《植物大战僵尸融合嫁接版》 该版本并没有对植物卡牌做改动&#xff0c;而是可以将任意两种植物叠放到一起进行融合&#xff0c;产生新…

2pc 3pc

2pc&3pc问题 本质&#xff1a; 2pcTM超时机制 3pc加入事务询问机制RM超时机制 事务询问机制&#xff1a;减少阻塞 RM超时机制&#xff1a;避免死锁 2pc 3pc 参考&#xff1a; https://juejin.im/post/5aa3c7736fb9a028bb189bca#heading-1 https://blog.csdn.net/xj1…

Windows 下用MSYS2 环境为RP2040 编译MicroPython 固件

就是想试试看MSYS2 能兼容到什么地步。自己做了个RP2040 板子&#xff0c;用了4MB 的Flash&#xff0c;默认的Micropython 固件是2MB 的&#xff0c;所以只能自己编译固件。 编译环境 MSYS2 的安装方法、基本配置什么的我就不管了&#xff0c;到处都有文章介绍这个。只提一点…

一次建表语句触发的ORA-600报错分析

​ 某次在客户Oracle数据库执行一条建表语句时&#xff0c;报出ORA-600错误。 报错代码如下&#xff1a; ORA-00600: 内部错误代码, 参数: [rwoirw: check ret val], [], [], [], [], [], [], [], [], [], [], [] 相关的建表语句如下&#xff1a; ​ 在报错发生后&#xff0c;…

拆解COLA框架

COLA 是 Clean Object-Oriented and Layered Architecture的缩写&#xff0c;代表“整洁面向对象分层架构”。由阿里大佬张建飞所提出的一种基于DDD和代码整洁理论所诞生的实践理论框架&#xff0c;详细内容可阅读《程序员的底层思维》和相关git代码去了解 项目地址&#xff1a…

毕业论文初稿写作方法与过程

毕业论文初稿写作方法与过程 毕业论文是大学生在学业结束前必须完成的一项重要任务&#xff0c;它不仅是对学生所学知识的综合运用&#xff0c;也是对学生研究能力和写作能力的检验。写好毕业论文初稿是完成高质量毕业论文的关键一步。下面将具体阐述毕业论文初稿的写作方法和过…

【MySQL】 NDB 集群概述

MySQL NDB&#xff08;Network Database&#xff09;是MySQL的一个存储引擎&#xff0c;也称为NDB Cluster存储引擎。它主要用于构建高可用性、高可扩展性和高性能的分布式数据库集群。NDB Cluster是MySQL的一个特殊版本&#xff0c;专门设计用于处理大规模的分布式数据存储和处…

「C++系列」C++ 变量作用域

文章目录 一、C 变量作用域二、局部变量三、全局变量四、类作用域五、相关链接 一、C 变量作用域 在C中&#xff0c;变量的作用域&#xff08;Scope&#xff09;指的是变量在程序中可以被访问的区域。作用域由花括号{}定义&#xff0c;这些花括号可以出现在函数体、控制结构&a…

[C++]——同步异步日志系统(2)

同步异步日志系统 一、 不定参函数1.1 不定参宏函数的使用1.2 C 语言中不定参函数的使用1.3 C不定参数使用 二、设计模式2.1 单列模式2.2 工厂模式2.3 建造者模式2.4 代理模式 在我们开发同步异步日志系统之前&#xff0c;需要了解一些相关的技术知识。 一、 不定参函数 在初学…

WPF UI 界面布局 魔术棒 文字笔记识别 技能提升 布局功能扩展与自定义 继承Panel的对象,测量与排列 系列七

应用开发第一步 功能分类&#xff1a;页面上的功能区域划分。。。。需求分析 业务逻辑 数据流 功能模块 UI/UX 编码 测试 发布 功能开发与布局 不用显式的方式设定元素的尺寸 不使用屏幕坐标来指定位置 Grid 功能最强大&#xff0c;布局最灵活的容器…

视频融合共享平台LntonCVS视频监控汇聚平台工业视频监控系统

LntonCVS是一款功能强大、灵活部署的安防视频监控平台&#xff0c;具备广泛的扩展性和视频能力。它支持多种主流标准协议&#xff0c;如国标GB28181、RTSP/Onvif、RTMP&#xff0c;同时还能兼容厂家的私有协议和SDK&#xff0c;如海康Ehome、海大宇等。除了传统的安防监控功能外…

阿里巴巴Arthas分析调优JVM实战及常量池详解

目录 一、阿里巴巴Arthas详解 Arthas使用场景 Arthas命令 Arthas使用 二、GC日志详解 如何分析GC日志 CMS G1 GC日志分析工具 三、JVM参数汇总查看命令 四、Class常量池与运行时常量池 字面量 符号引用 五、字符串常量池 字符串常量池的设计思想 三种字符串操作…

Linux 账号安全管理及应用

一、账号安全控制 1.系统账号清理 1.1 将非登录用户设置为无法登录 usermod -s /etc/nologin pkm #将名为pkm 用户的shell设为/sbin/nologin 用户 pkm 将无法登录 1.2 锁定长期不使用的账号 usermod -L 用户名 #锁定用户账号密码 usermod -U …

TCP报文校验和(checksum)计算

一. 原理 将TCP相关内容&#xff08;TCP伪头部TCP头部TCP内容&#xff09;转换成16比特的字符&#xff0c;然后进行累加&#xff0c;最后结果进行取反。TCP伪头部是固定的&#xff0c;下文有相关代码展示。 二. 源码 源码 #include <stdio.h> #include <stdlib.h&…

在 VS Code 中自动化 Xcode 项目编译和调试

在 VS Code 中自动化 Xcode 项目编译和调试 在日常的开发工作中&#xff0c;Xcode 是 macOS、iOS、watchOS 和 tvOS 应用程序开发的主要工具。为了提高工作效率&#xff0c;许多开发者选择在 Visual Studio Code (VS Code) 中编辑代码&#xff0c;并希望能够直接从 VS Code 启…

人工智能系列-numpy(一)

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” Numpy是python语言的一个拓展程序库&#xff0c;支持大量的维度数组与矩阵计算&#xff0c;此外也针对数组运算提供大量的数学函数库 NumPy支持的数据类型比Python内置的类型要…

系统架构设计师教程(清华第2版)<第1章 绪论>解读

系统架构设计师教程 第一章 绪论 1.1 系统架构概述1.1.1 系统架构的定义及发展历程1.1.2 软件架构的常用分类及建模方法1.1.3 软件架构的应用场景1.1.4 软件架构的发展未来1.2 系统架构设计师概述1.2.1 架构设计师的定义、职责和任务1.2.2 架构设计师应具备的专业素质1.3 如何成…

计算机的错误计算(二十一)

摘要 两个不相等数相减&#xff0c;差为0&#xff1a; ? 在计算机的错误计算&#xff08;十九&#xff09;中&#xff0c;高中生小明发现本应为0的算式结果不为0. 今天他又发现对本不为0的算式&#xff0c;计算机的输出为0. 在 Python 中计算 &#xff1a; 则输出为0. 若用 C…