从零开始掌握LVGL图形库开发(上)
·
一、LVGL的相关资料说明
- 说明:Light and versatile Graphic Library(轻巧且功能多样化的图形库)
(1)、官方网站链接:
1、英文资料(推荐)
https://lvgl.io/ (官网主界面)
https://docs.lvgl.io/8.3/index.html (相关开发文档界面)

2、中文资料
http://lvgl.100ask.net/8.2/index.html (相关开发文档界面)

(2)、如何学习LVGL?
1、使用网页在线例程 来体验LVGL
2、阅读文档 Introduction(介绍) 章节来初步了解LVGL
3、再来阅读一下文档 Quick overview(快速概览) 章节来了解LVGL的基本知识
4、学习如何使用 Simulator on PC(PC端模拟器) 来在电脑上仿真LVGL
5、试着动手实践一些 Examples(示例)
6、查看特定于平台的教程。(在下面的本节中)。
7、参考移植指南尝试将LVGL Porting(移植) 到一块开发板上,LVGL也已经提供了一些移植好的 工程
8、仔细阅读文档Overview(概述) 章节来更加深入的了解和熟悉LVGL(2-3小时)
9、浏览文档 Widgets(控件) 章节来了解如何使用它们
10、如果你有问题可以到LVGL 论坛 提问
11、阅读文档Contributing(贡献) 章节来看看你能帮LVGL社区做些什么,以促进LVGL软件质量的不断提

二、X86环境搭建(在桌面端运行起LVGL)
(1)、如何下载(直接在官网下载即可)
下载链接:https://github.com/lvgl/lv_port_pc_eclipse/tree/release/v8.3
注意选择v8.3版本:
1、下载LVGL的模板

2、下载LVGL的硬件驱动drivers文件

3、下载LVGL的核心代码文件

- 注意:如果不想在官网下载,点赞+关注+收藏三连可评论区留言获取(或者私信博主)
(2)、解压并放置各文件夹
- 需要注意的是:有时候解压缩之后的文件夹,有多重嵌套子文件夹,须确保不能嵌套多重文件夹,即在 lv_drivers 下和 lvgl 下必须有 CMakeLists.txt。
1、在windows系统桌面上,创建一个合适文件夹,用来放置LVGL的各个文件(名字最好短一点)

2、将LVGL模板的文件都拖拽进你自己创建的文件夹

3、将LVGL的硬件驱动drivers文件都拖拽进上一步自己文件夹下的lv_drivers的文件夹下

4、将核心代码文件都拖拽进上一步自己文件夹下的lvgl的文件夹下

(3)、下载配置MinGW
- 说明:MinGW(Minimalist GNU for Windows)是一个可以在Windows平台上提供轻量级、最小化的GNU工具集,使开发者能够在Windows环境下使用类Unix的工具和编程环境。MinGW的主要组成部分包括:
- GCC(GNU Compiler Collection): 一个强大的编译器套件,包括C、C++、Fortran等语言的编译器。
- Binutils: 一组用于处理二进制文件的工具,包括汇编器、链接器等。
- MSYS(Minimal SYStem): 一个提供类Unix shell环境的工具,使得在Windows环境下使用GNU工具更为方便。
- 目标:MinGW的主要目标是让开发者能够在Windows上使用开源和跨平台的软件开发工具,而无需依赖于Microsoft Visual Studio等闭源工具。使用MinGW,开发者可以编写和编译与Windows API无关的本地应用程序,这对于跨平台开发和移植代码至Windows平台是非常有用的。
1、解压Mingw64.zip到你自己电脑合适的位置(注意1:不要有中文路径, 注意2:如果之前有装cygwin64环境的同学,建议将其环境变量删除)

- 删除cygwin64的环境变量:

2、解压 MinGW,并将 bin/ 文件夹设置到 环境变量 PATH 中 (注意不能有中文路径):

3、在命令行中测试是否安装成功:
->win键+R键打开搜索库
-> 输入cmd命令

-> 输入where gcc,查询gcc在何处,有的话,证明安装成功了

(4)、配置SDL2
- 说明:SDL2 的全称是 Simple DirectMedia Layer 2(简易直媒体层2)。它是一个开源、跨平台的多媒体开发库,主要用于提供对音频、键盘、鼠标、游戏手柄和图形硬件的低级访问。简单来说,SDL2 是一个工具包,它让程序员可以用一套统一的代码,轻松地为 Windows、macOS、Linux、Android、iOS 等多种操作系统开发游戏和多媒体应用。所以如果你的LVGL要在windows系统下,全部功能想要运行起来,需要用到它
- Windows的LVGL模拟器基于 SDL2 运行,SDL2 位于 :

1、将此目录下的 SDL2.dll 拷贝到 lv_port_pc_v8.3\bin 目录下,如果没有这个bin目录,可以手工创建一个。

2、调整SDL模拟器的窗口分辨率(可令其等于开发板的LCD分辨率):

(5)、下载、配置cmake
- 说明:cmake是跨平台工程管理工具,在用来管理配置整个LVGL的工程编译工作。下载下面的cmake并安装到Windows中 (注意安装路径不要有中文):
- 注意:博主已经为你们准备好了,点赞三连,评论区或者私信领取

- 安装时注意

(6)、配置VSCode软件
1、安装cmake、cmaketools插件:

2、配置 cmaketools :

- 注意: 当需要在Windows和ARM交叉编译环境切换时,上述 Generator也需同步在 MinGW Makefiles 和 Unix Makfiles之间切换。
3、设置构建LVGL的工具链
- 注意:如果没有出现以下选项,则重新来一遍或者最好重启系统

4、点击 ”生成“ 按钮,开始编译:

5、点击三角号,运行得到官方示例:

- 注意:修改如下宏定义,可启停上述demo例程的边角监控信息:

三、ARM环境搭建(在开发板上运行起LVGL)
- 注意:
- 你的工程不能有中文路径,否则有可能会造成编译器无法识别的问题
- 单独打开lvgl工程
(1)、下载ARM平台LVGL源码包
下载链接:https://github.com/lvgl/lv_port_pc_eclipse/tree/release/v8.2
注意选择v8.2版本:
1、下载LVGL的模板

2、下载LVGL的硬件驱动drivers文件

3、下载LVGL的核心代码文件

- 注意:如果不想在官网下载,点赞+关注+收藏三连可评论区留言获取(或者私信博主)
(2)、解压并放置各文件夹
- 注意:有时候解压缩之后的文件夹,有多重嵌套子文件夹,须确保不能嵌套多重文件夹,即在 lv_drivers 下和 lvgl 下必须有 CMakeLists.txt。
1、在windows系统桌面上,创建一个合适文件夹,用来放置LVGL的各个文件(名字最好短一点)

2、将LVGL模板的文件都拖拽进你自己创建的文件夹

3、将LVGL的硬件驱动drivers文件都拖拽进上一步自己文件夹下的lv_drivers的文件夹下

4、将核心代码文件都拖拽进上一步自己文件夹下的lvgl的文件夹下

(3)、将你的工程进行裁剪,然后复制移动到ubuntu系统的家目录里面去,然后使用ssh进行远程连接
1、将不必要的文件和文件夹删除

2、复制移动到ubuntu系统的家目录中, 最好再赋予权限
终端命令1:cp /mnt/hgfs/你的共享文件夹/lv_port_linux_v8.2/ ~/ -rf
终端命令2:chmod 777 ~/lv_port_linux_v8.2/
- 现象

3、使用ssh进行远程链接

(4)、配置gec6818开发板的交叉编译环境
1、检查一下你自己安装交叉编译器的路径:
终端命令:which arm-linux-gcc
注意:博主的ubuntu系统交叉编译工具的路径:/home/mq/arm-linux_gcc-5.4.0/usr/
- 现象

2、检查一下你的交叉编译器能不能用:
终端命令1:arm-linux-gcc -v # 获取交叉编译器的版本
终端命令2:arm-linux-gcc main.c -o main # 编译程序
-
终端命令1的现象:

- 终端命令2的现象:

(5)、需要更改一下VScode软件上CMake Tools工具(远程)

- 修改一下你的编译器为unix平台

(6)、在工程里面创建CMakeLists.txt,并填写一下内容
cmake_minimum_required(VERSION 3.1)
project(main)
include_directories(.)
add_subdirectory(lvgl)
add_subdirectory(lv_drivers)
set(TOOLCHAIN_DIR "/home/mq/arm-linux_gcc-5.4.0/usr") # 比如:这个位置是博主的交叉编译工具链的位置
set(CMAKE_C_COMPILER "${TOOLCHAIN_DIR}/bin/arm-linux-gcc")
set(CMAKE_CXX_COMPILER "${TOOLCHAIN_DIR}/bin/arm-linux-g++")
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/build)
add_executable(${PROJECT_NAME} main.c mouse_cursor_icon.c)
target_link_libraries(${PROJECT_NAME} PRIVATE lvgl lvgl::examples lvgl::demos lvgl::drivers)
(7)、在创建CMakeLists.txt文件后,才会出现以下选择项(最后一行那里),这个时候我们选择一下自己的交叉编译工具即可

- 注意:如果出现以下问题,在ubuntu系统上安装一下cmake(sudo apt install cake)

(8)、配置输入设备(触摸屏及其分辨率)

- 注意:环境到这就全部安装完了,如果按照步骤来还是不行,建议把文件删了重启再配一遍
四、LVGL工程代码分析
(1)、整个工程目录的说明
1、X86环境(Windows)

- 说明
bin目录
main.exe:lvgl可执行文件,执行它后lvgl项目就会运行起来
SDL2.dll:windows系统下图形库(小),为了方便lvgl(我们现在用的是本质上是linux的x86环境)显示到window系统上
lv_drivers目录
解释:显示和输入设备的驱动程序,提供了硬件访问能力(包含了display(显示驱动)和indev(输入设备驱动)、sdl等子目录)
lvgl目录:
解释: 包含了LVGL图形库的核心源代码(如:控件、绘图、主题等)
demos: 展示LVGL功能的完整示例程序,用于展示库的强大功能和最佳实践(老手)******
examples: 简单的代码示例,用于演示特定功能或控件的基本用法(比demo简单,更适合学习)(新手)******
src: LVGL核心库的源代码(又是与LVGL文件夹重复,但通常src是更常见的源代码目录名)---参考
CMakeLists.txt
注意:只要改变了此处的配置,你的工程下次将会全编译一遍
解释:用来编译我们LVGL工程
lv_conf.h
注意:只要改变了此处的配置,你的工程下次将会全编译一遍
解释:用于剪裁和配置LVGL库本身的功能,如启用/禁用控件,设置内存大小、屏幕分辨率等
lv_drv_conf.h
注意:只要改变了此处的配置,你的工程下次将会全编译一遍
解释:用于配置lv_drivers中的驱动程序,如选择使用哪种显示设备(FBDEV)、输入设备(EVDEV)及其参数
例子:显示屏(间接调用了window系统的sdl库从而使用显示屏驱动)
main.c文件
解释:你调用lvgl各个库地方。工程第一个执行的文件
2、ARM环境(Linux/开发板)
- 工程图示

- 说明:
lv_drivers目录
解释:显示和输入设备的驱动程序,提供了硬件访问能力(包含了display(显示驱动)和indev(输入设备驱动)、sdl等子目录)
lvgl目录
解释:包含了LVGL图形库的核心源代码(如:控件、绘图、主题等)
demos: 展示LVGL功能的完整示例程序,用于展示库的强大功能和最佳实践(老手)******
examples: 简单的代码示例,用于演示特定功能或控件的基本用法(比demo简单,更适合学习)(新手)******
src: LVGL核心库的源代码(又是与LVGL文件夹重复,但通常src是更常见的源代码目录名)---参考
CMakeLists.txt
注意:只要改变了此处的配置,你的工程下次将会全编译一遍
解释:用来编译我们LVGL工程
lv_conf.h
注意:只要改变了此处的配置,你的工程下次将会全编译一遍
解释:用于剪裁和配置LVGL库本身的功能,如启用/禁用控件,设置内存大小、屏幕分辨率等、
lv_drv_conf.h
注意:只要改变了此处的配置,你的工程下次将会全编译一遍
解释:用于配置lv_drivers中的驱动程序,如选择使用哪种显示设备(FBDEV)、输入设备(EVDEV)及其参数
例子:触摸屏
main.c文件
解释:你调用lvgl各个库地方,工程第一个执行的文件
(2)、CMakeLists.txt说明
1、X86环境
# 1.CMake基础设置
cmake_minimum_required(VERSION 3.10) # 要求cmake最低版本3.10
project(lvgl) # 项目名称为:lvgl
set(CMAKE_C_STANDARD 11)#C11 # C语言标准设置为C11
set(CMAKE_CXX_STANDARD 17)#C17 # C++语言标准设置为C17
set(CMAKE_CXX_STANDARD_REQUIRED ON) # 强制要求使用指定的C++标准
# 2.包含(头文件)目录设置
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}) # 将项目了添加到包含路径下
# 3.文件收集
# a.收集所有头文件路径
file(GLOB_RECURSE INCLUDES
"lv_drivers/*.h" # lv_drivers目录及其子目录的所有.h文件
"lvgl/demos/*.h" # lvgl/demos目录及其子目录的所有.h文件
"lvgl/*.h" # lvgl目录及其子目录的所有.h文件
"lvgl/examples/*.h" # lvgl/examples目录及其子目录的所有.h文件
"./*.h" # 当前目录及其子目录的所有.h文件
"my_inc/*.h" # my_inc目录及其子目录的所有.h文件
)
# b. 收集所有源文件路径
file(GLOB_RECURSE SOURCES
"lv_drivers/*.c" # lv_drivers目录及其子目录的所有.c文件
"lvgl/demos/*.c" # lvgl/demos目录及其子目录的所有.c文件
"lvgl/src/*.c" # lvgl/src目录及其子目录的所有.c文件
"lvgl/examples/*.c" # lvgl/examples目录及其子目录的所有.c文件
"my_src/*.c" # my_src目录及其子目录的所有.c文件
)
# 4. 输出和编译设置
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/build) # 可执行文件输出到工程中的bin目录下
SET(CMAKE_CXX_FLAGS "-O3") # 设置C++编译优化级别为O3(最高优化)
# 5. SDL2依赖配置
find_package(SDL2 REQUIRED SDL2) # 查找并要求SDL2库
include_directories(${SDL2_INCLUDE_DIRS}) # 添加SDL2的头文件目录
# 6. 构建目标(创建可执行文件main, 包含所有源文件)
add_executable(main
main.c
${SOURCES}
${INCLUDES}
)
# 7. 定义预处理宏
add_compile_definitions(LV_CONF_INCLUDE_SIMPLE)
# 8. 链接SDL2库到可执行文件
target_link_libraries(main PRIVATE SDL2 )
# 9.自定义目标(创建一个名为run的自定义目标,用于运行生成的可执行文件)
add_custom_target (run COMMAND ${EXECUTABLE_OUTPUT_PATH}/main)
2、ARM环境
# 1.CMake基础设置
cmake_minimum_required(VERSION 3.1) # 要求cmake最低版本3.1
project(main) # 项目名称为:main
include_directories(.) # 将当前目录添加到包含路径
# 2. 添加子目录(LVGL组件)
add_subdirectory(lvgl) # 添加lvgl子目录(包含LVGL核心库)
add_subdirectory(lv_drivers) # 添加lv_drivers子目录(包含驱动程序)
# 3. 交叉编译工具链配置(关键部分)
set(TOOLCHAIN_DIR "/home/mq/arm-linux_gcc-5.4.0/usr") # 工具链的安装路径
set(CMAKE_C_COMPILER "${TOOLCHAIN_DIR}/bin/arm-linux-gcc") # 设置C编译器为ARM版本
set(CMAKE_CXX_COMPILER "${TOOLCHAIN_DIR}/bin/arm-linux-g++") # 设置C++编译器为ARM版本
# 4. 输出目录设置
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/build) # 可执行输出到build目录下
# 5.文件收集
# a.收集所有头文件路径
file(GLOB_RECURSE INCLUDES
"my_inc/*.h" # my_inc目录及其子目录的所有.h文件
)
# b. 收集所有源文件路径
file(GLOB_RECURSE SOURCES
"my_src/*.c" # my_src目录及其子目录的所有.c文件
)
# 6. 构建目标(创建可执行文件main, 包含所有源文件)
add_executable(${PROJECT_NAME}
main.c
${SOURCES}
${INCLUDES}
)
# mouse_cursor_icon.c在开发板上不需要,所以可以注释
# 7. 链接库
target_link_libraries(${PROJECT_NAME} PRIVATE
lvgl # LVGL核心库
lvgl::examples # LVGL示例库
lvgl::demos # LVGL演示例程
lvgl::drivers # LVGL驱动程序
)
(3)、main.c说明
1、X86环境:这是一个使用SDL2作为后端的LVGL模拟器程序,允许在PC上开发和测试LVGL应用程序
// (1)、头文件包含
#define _DEFAULT_SOURCE // 启用usleep()等函数
#include <stdlib.h>
#include <unistd.h>
#define SDL_MAIN_HANDLED // 修复SDL的WinMain问题
#include <SDL2/SDL.h> // SDL2图形库
#include "lv_drivers/sdl/sdl.h" // SDL的驱动程序
#include "lvgl/lvgl.h" // LVGL核心库
#include "lvgl/examples/lv_examples.h" // LVGL示例库(新手)
#include "lvgl/demos/lv_demos.h" // LVGL演示程序(老手)
#include "my_inc/my_func.h" // 自己写的库
// (2)、静态函数
static void hal_init(void);
// (3)、主函数
int main(int argc, char **argv)
{
// 1、初始化LVGL库
lv_init();
// 2、初始化SDL的硬件抽象层(比如:显示、输入设备,滴答定时器)
hal_init();
// 3、创建演示界面
// a、使用的是lv_examples的LVGL示例库(新手)
// lv_example_switch_1();
// lv_example_calendar_1();
// lv_example_btnmatrix_2();
// lv_example_checkbox_1();
// lv_example_colorwheel_1();
// lv_example_chart_6();
// lv_example_table_2();
// lv_example_scroll_2();
// lv_example_textarea_1();
// lv_example_msgbox_1();
// lv_example_dropdown_2();
// lv_example_btn_1();
// lv_example_scroll_1();
// lv_example_tabview_1();
// lv_example_tabview_1();
// lv_example_flex_3();
// lv_example_label_1();
// b、使用的是lv_demos的LVGLLVGL演示程序(老手)
lv_demo_widgets();
// c、自己写的库
MY_FUNC_Printf();
// 4、主循环 --- 处理LVGL任务
while(1)
{
lv_timer_handler(); // 处理LVGL定时器和任务
usleep(5 * 1000); // 休眠5ms(约200FPS)
}
return 0;
}
// (4)、硬件抽象层初始化函数
/**
* @brief 硬件抽象层初始化
* @note 初始化输出设备驱动(SDL2代替了)、输入设备驱动(鼠标(滚动,位置)、键盘)
* @param None
* @retv None
*
*/
static void hal_init(void)
{
// 1、初始化SDL窗口和渲染器(输出显示)
sdl_init();
// a、创建显示缓冲区
static lv_disp_draw_buf_t disp_buf1;
static lv_color_t buf1_1[SDL_HOR_RES * 100]; // 缓冲区的大小
lv_disp_draw_buf_init(&disp_buf1, buf1_1, NULL, SDL_HOR_RES * 100);
// b、配置显示驱动
static lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.draw_buf = &disp_buf1; // 设置绘制缓冲区
disp_drv.flush_cb = sdl_display_flush; // SDL刷新回调
disp_drv.hor_res = SDL_HOR_RES; // 使用SDL定义的水平分辨率
disp_drv.ver_res = SDL_VER_RES; // 使用SDL定义的水平分辨率
lv_disp_t * disp = lv_disp_drv_register(&disp_drv); // 注册显示驱动
// c、主题设置 // 主颜色:蓝色 次要颜色:红色 深色主题 默认字体
lv_theme_t * th = lv_theme_default_init(disp, lv_palette_main(LV_PALETTE_BLUE), lv_palette_main(LV_PALETTE_RED), LV_THEME_DEFAULT_DARK, LV_FONT_DEFAULT);
lv_disp_set_theme(disp, th); // 应用主题
// 2、输入设备初始化
lv_group_t *g = lv_group_create();
lv_group_set_default(g);
// A、鼠标输入设备
// a、添加鼠标作为输入设备,使用读取电脑鼠标的 'mouse' 驱动程序
static lv_indev_drv_t indev_drv_1;
lv_indev_drv_init(&indev_drv_1); /*Basic initialization*/
indev_drv_1.type = LV_INDEV_TYPE_POINTER;
// b、该函数将被(库)定期调用以获取鼠标位置和状态
indev_drv_1.read_cb = sdl_mouse_read;
lv_indev_t *mouse_indev = lv_indev_drv_register(&indev_drv_1);
// B、键盘输入设备
static lv_indev_drv_t indev_drv_2;
lv_indev_drv_init(&indev_drv_2); /*Basic initialization*/
indev_drv_2.type = LV_INDEV_TYPE_KEYPAD;
indev_drv_2.read_cb = sdl_keyboard_read;
lv_indev_t *kb_indev = lv_indev_drv_register(&indev_drv_2);
lv_indev_set_group(kb_indev, g);
// C、编码器输入设备(模拟鼠标滚轮)
static lv_indev_drv_t indev_drv_3;
lv_indev_drv_init(&indev_drv_3); /*Basic initialization*/
indev_drv_3.type = LV_INDEV_TYPE_ENCODER;
indev_drv_3.read_cb = sdl_mousewheel_read;
lv_indev_t * enc_indev = lv_indev_drv_register(&indev_drv_3);
lv_indev_set_group(enc_indev, g);
// // D、设置自定义的鼠标光标
// LV_IMG_DECLARE(mouse_cursor_icon); /*Declare the image file.*/
// lv_obj_t * cursor_obj = lv_img_create(lv_scr_act()); /*Create an image object for the cursor */
// lv_img_set_src(cursor_obj, &mouse_cursor_icon); /*Set the image source*/
// lv_indev_set_cursor(mouse_indev, cursor_obj); /*Connect the image object to the driver*/
}
2、ARM环境
// (1)、头文件包含
#include <unistd.h> // Linux系统调用
#include <pthread.h> // 线程支持 --- 系统编程
#include <time.h> // 时间函数
#include <sys/time.h> // 系统时间
#include "lv_drivers/display/fbdev.h" // 显示驱动(FrameBuffer)
#include "lv_drivers/indev/evdev.h" // 输入设备驱动(evdev)
#include "lvgl/lvgl.h" // LVGL核心库
#include "lvgl/examples/lv_examples.h" // LVGL示例库(新手)
#include "lvgl/demos/lv_demos.h" // LVGL演示程序(老手)
#include "my_inc/my_func.h" // 自己写的库
// (2)、宏定义声明
#define DISP_BUF_SIZE (128 * 1024)
// (2)、函数声明
static void hal_init(void);
uint32_t custom_tick_get(void);
// (4)、主函数
int main(void)
{
// 1、初始化LVGL库
lv_init();
// 2、初始化硬件抽象层
hal_init();
// 3、创建演示界面
// a、使用的是lv_examples的LVGL示例库(新手)
// lv_example_switch_1();
// lv_example_calendar_1();
// lv_example_btnmatrix_2();
// lv_example_checkbox_1();
// lv_example_colorwheel_1();
// lv_example_chart_6();
// lv_example_table_2();
// lv_example_scroll_2();
// lv_example_textarea_1();
// lv_example_msgbox_1();
// lv_example_dropdown_2();
// lv_example_btn_1();
// lv_example_scroll_1();
// lv_example_tabview_1();
// lv_example_tabview_1();
// lv_example_flex_3();
// lv_example_label_1();
// b、使用的是lv_demos的LVGLLVGL演示程序(老手)
lv_demo_widgets();
// c、自己写的库
MY_FUNC_Printf();
// 4、主循环 --- 处理LVGL任务
while(1)
{
lv_timer_handler(); // 处理LVGL定时器和任务
usleep(5 * 1000); // 休眠5ms(约200FPS)
}
return 0;
}
// (4)、硬件抽象层初始化函数
/**
* @brief 硬件抽象层初始化
* @note 初始化输出设备驱动(SDL2代替了)、输入设备驱动(鼠标(滚动,位置)、键盘)
* @param None
* @retv None
*/
static void hal_init(void)
{
// 1、显示部分(显示屏)
fbdev_init();
// a、创建显示缓冲区
static lv_color_t buf[DISP_BUF_SIZE];
static lv_disp_draw_buf_t disp_buf;
lv_disp_draw_buf_init(&disp_buf, buf, NULL, DISP_BUF_SIZE);
// b、配置显示驱动
static lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.draw_buf = &disp_buf;
disp_drv.flush_cb = fbdev_flush;
disp_drv.hor_res = 800;
disp_drv.ver_res = 480;
lv_disp_drv_register(&disp_drv);
// 2、输入部分(触摸屏、鼠标)
evdev_init();
// a、配置触摸屏驱动
static lv_indev_drv_t indev_drv_1;
lv_indev_drv_init(&indev_drv_1); /*Basic initialization*/
indev_drv_1.type = LV_INDEV_TYPE_POINTER;
indev_drv_1.read_cb = evdev_read;
lv_indev_t *mouse_indev = lv_indev_drv_register(&indev_drv_1);
// b、注释掉的鼠标光标图标位置(配置鼠标驱动)
// /*Set a cursor for the mouse*/
// LV_IMG_DECLARE(mouse_cursor_icon)
// lv_obj_t * cursor_obj = lv_img_create(lv_scr_act()); /*Create an image object for the cursor */
// lv_img_set_src(cursor_obj, &mouse_cursor_icon); /*Set the image source*/
// lv_indev_set_cursor(mouse_indev, cursor_obj); /*Connect the image object to the driver*/
}
// (5)、硬件抽象层初始化函数
/**
* @brief 自定义时间函数
* @note 提供从程序启动开始的毫秒数、用于LVGL的动画的定时器系统、需要在lv_conf.h中配置LV_TICK_CUSTOM_SYS_TIME_EXPR
* @param None
* @retv None
*/
uint32_t custom_tick_get(void)
{
static uint64_t start_ms = 0;
if(start_ms == 0) {
struct timeval tv_start;
gettimeofday(&tv_start, NULL);
start_ms = (tv_start.tv_sec * 1000000 + tv_start.tv_usec) / 1000;
}
struct timeval tv_now;
gettimeofday(&tv_now, NULL);
uint64_t now_ms;
now_ms = (tv_now.tv_sec * 1000000 + tv_now.tv_usec) / 1000;
uint32_t time_ms = now_ms - start_ms;
return time_ms;
}
五、如何将自己的工程加入到LVGL工程中,并应用?
(1)、X86环境
1、创建my_inc和my_src文件夹到LVGL工程中,并在相应的文件夹里创建.h和.c文件

- my_func.h文件内容:
/**
******************************************************************************
* @file my_func.h
* @author MChine慕青
* @version V0.0.1
* @date 2025.09.26
* @brief 普通的函数
*
******************************************************************************
* @attention
*
* 本文档只供学习使用,不得商用,违者必究
*
* 个人博客网: https://blog.csdn.net/2402_83622972?spm=1011.2415.3001.5343
* 有疑问或者建议:3211735057@qq.com
*
******************************************************************************
*/
#ifndef __MY_FUNC_H // 定义以防止递归包含
#define __MY_FUNC_H
// (1)、其它头文件
#include <stdio.h>
// (2)、宏定义(函数、变量、常量)
// (3)、自定义类型(结构体、联合体、枚举、函数指针类型等...)
// (4)、函数声明
// (5)、全局变量声明
extern int MY_FUNC_Printf(void);
// (6)、静态函数定义
// (7)、静态变量定义
#endif
- my_func.c文件内容:
#include "../my_inc/my_func.h"
/**
* @brief: 打印数据
* @note: None
* @param: None
* @retval: 成功:返回0
* 失败:返回非0
*/
int MY_FUNC_Printf(void)
{
printf("hello MY_FUNC_Printf!\n");
return 0;
}
2、在CMakeLists.txt文件中加入你.h和.c的文件路径

3、在main.c中声明并调用即可
- 声明

- 调用:

(2)、ARM环境
1、创建my_inc和my_src文件夹到LVGL工程中,并在相应的文件夹里创建.h和.c文件

- my_func.h文件内容:
/**
******************************************************************************
* @file my_func.h
* @author MChine慕青
* @version V0.0.1
* @date 2025.09.26
* @brief 普通的函数
*
******************************************************************************
* @attention
*
* 本文档只供学习使用,不得商用,违者必究
*
* 个人博客网: https://blog.csdn.net/2402_83622972?spm=1011.2415.3001.5343
* 有疑问或者建议:3211735057@qq.com
*
******************************************************************************
*/
#ifndef __MY_FUNC_H // 定义以防止递归包含
#define __MY_FUNC_H
// (1)、其它头文件
#include <stdio.h>
// (2)、宏定义(函数、变量、常量)
// (3)、自定义类型(结构体、联合体、枚举、函数指针类型等...)
// (4)、函数声明
// (5)、全局变量声明
extern int MY_FUNC_Printf(void);
// (6)、静态函数定义
// (7)、静态变量定义
#endif
- my_func.c文件内容:
#include "../my_inc/my_func.h"
/**
* @brief: 打印数据
* @note: None
* @param: None
* @retval: 成功:返回0
* 失败:返回非0
*/
int MY_FUNC_Printf(void)
{
printf("hello MY_FUNC_Printf!\n");
return 0;
}
2、在CMakeLists.txt文件中加入你.h和.c的文件路径

3、在main.c中声明并调用即可
- 声明:

- 调用:

六、调用LVGL自带的示例库和演示程序
(1)、示例库
- 说明:如何找到示例库并获取其功能函数

- 找到后,复制到主函数上进行调用

- X86环境、ARM环境都是直接打开即可:

(2)、演示程序
- 说明:通常来说,使用演示程序的时候,我们看其.h文件,找到有GLOBAL的字样的注释,下面的那个函数一般就是这个演示程序功能集合

- 找到后,复制到主函数上进行调用

- 注意:X86环境、ARM环境操作一致:
- 编译出现的问题:

- 原因:通常来说是因为LVGL默认将其屏蔽了,因为编译起来会比较大,而且慢
- 解决方法:

- 注意:使用music演示程序的时候,此处还需要打开一下

结语:LVGL(Light and Versatile Graphics Library)是一款开源嵌入式图形库,专为资源受限设备设计。其核心优势在于轻量级架构与丰富功能的平衡,支持多种显示驱动和输入设备接口。本期重点解析了整个工程,下期将深入动画效果和主题定制。
更多推荐



所有评论(0)