STM32F407移植LVGL(V8.3版本)

news2024/9/25 23:11:50

一、LVGL简述

1.丰富且强大的模块化图形组件:按钮、图表、列表、滑条、图片等
2.高级图形引擎:动画、抗锯齿、透明度、平滑滚动、图层混合等效果
3.支持多种输入设备:触摸屏、键盘、编码器、按键等
4.配置可裁剪,最低资源占用:64K Flash,16K RAM
5.基于UTF-8的多语种支持,例如中文、日文、韩文、阿拉伯文等
6.支持操作系统、外置内存、以及硬件加速
7.支持模拟器仿真,可以无硬件进行开发

二、准备STM32工程(裸机)

1.硬件要求
芯片资源:Flash>128K,RAM>64K;(LVGL至少占用:Flash>64K,RAM>16K)
显示屏:建议使用16位色深的彩屏, 1.44寸、2.8寸、4.3寸等等
不建议使用常用的0.96寸OLED屏,指甲大小的单色屏,耗100K资源去撑它,没搞头
2.STM32工程要求
堆栈大小:Heap、Stack,设置为:0x1000; 
准备:画点函数,用于后面注册LVGL的显示功能;
准备:触摸检测函数 (返回:0-未按下、1-按下)、坐标获取函数,用于注册LVGL的触屏功能;

三、下载LVGL

v8.3版本,网上教程资源众多、移植简单,是目前最广泛使用的版本
官方下载链接:https://github.com/lvgl/lvgl

在这里插入图片描述
需要用到的是上图中的3个文件夹 + 2个h文件

四、源文件裁剪

1.在keil工程目录下 Middlewares 文件夹中新建LVGL文件夹,把上面的3个文件夹 + 2个h文件放进去
“lv_conf_template.h”,是LVGL配置参数的重要文件。
2.原文件名:“lv_conf_template.h”,修改为: “lv_conf.h”;
3.删除不需要的文件夹
打开文件夹:“LVGL / examples”:只保留 porting 文件夹,其它的文件夹和文件,都删除掉
4、修改 porting 里面的文件名称
6个文件的名称,都删除 “_template” 字样

这个 “LVGL” 文件夹,以后可以复制给各类的工程使用,不限于STM32的工程,通用

五、STM32工程添加 LVGL 文件

1.打开Keil,在工程里,添加4个文件夹(Groups);
在这里插入图片描述
2.为每一个文件夹组(Groups),添加需要的文件
在这里插入图片描述

3.添加头文件

打勾C99,并,添加3个头文件路径:

添加:LVGL 文件夹的路径

添加:LVGL\src 文件夹的路径

添加:LVGL\examples\porting 文件夹的路径

4.编译
在这里插入图片描述
六、注册显示
1.启用 lv_conf.h
双击打开 lv_conf.h,对以下内容进行修改,以启用此文件
第15行,原:#if 0,修改为:#if 1
2、启用 lv_port_disp.h
双击打开 lv_port_disp.h,修改以下内容,以启用此文件:
第7行,原:#if 0, 修改为:#if 1
第22行,原:“lvgl/lvgl.h", 修改为:”lvgl.h"
3、启用 lv_port_disp.c
双击打开 lv_port_disp.c,修改以下内容,以启用此文件:
第7行,原:#if 0, 修改为:#if 1
第12行,原"lv_port_disp_template.h", 修改为:“lv_port_disp.h”
4、添加 LCD 驱动的头文件
在 lv_port_disp.c中:
第14行,插入你的LCD驱动文件,如:#include “./BSP/LCD/lcd.h”,写上你的h文件。
第20行、第25行,是显示屏的宽、高度。查看你的显示屏参数,填写实际像素即可。
插入LCD的头文件,目的是为了让这个c文件,能调用LCD的画点函数;
注意一个:LVGL默认使用横屏的方式,这一点要注意,别写反了。
5、选择创建缓存的方式,3选1
还是在 lv_port_disp.c 中,
第86行到101行,LVGL 提供了创建显示缓冲区的3种方式,这里,必须3选1。
绝大多数情况下,使用第1种方法,即:只创建1个缓冲区;
注释掉第90~101行,即:不使用第2和第3种方法;
6、关联 画点函数
还是在 lv_port_disp.c 中,向下滚动,找到disp_flush( )函数:
第173行,替换你的 LCD 的画点函数; 参数:x坐标、y坐标、16位颜色值。
小编用的画点函数:lcd_draw_point(x, y, color_p->full);
这里给LVGL一个画点函数后, LVGL就能完成需要的显示操作了。

至此,显示部分的修改、注册,已完成。点击编译:0 Erros。

七、注册 触摸屏

1、启用 “lv_port_indev.h”
打开"lv_port_indev.h", 修改以下内容,以启动此文件:
第8行,原:#if 0, 修改成:#if 1
第20行,原:“lvgl / lvgl.h”, 修改成:“lvgl.h”
2、启动 “lv_port_indev.c”
打开"lv_port_indev.c", 修改以下内容,以启动此文件:
第 7行,原:#if 0, 修改为:#if 1
第12行,原:“lv_port_indev_template.h", 修改为:“lv_port_indev.h”
第13行,原:“…/…/lvgl.h”,修改为:“lvgl.h”
3、添加 触屏 的驱动头文件
还是在 “lv_port_indev.c” 中:
第14行,插入:#include “触摸屏的头文件”,小编这边是:
#include “./BSP/TOUCH/touch.h”
目的是为了让这个c文件,能调用触屏的:触摸状态检测函数、坐标获取函数;
4、注释掉不需要的输入任务注册
还是在 “lv_port_indev.c” 中,
向下滚动至大约70行,找到输入注册函数:lv_port_indev_init( ),
函数内有5种输入方式的任务注册:触屏、鼠标、键盘、编码器、物理按键;
保留触摸屏输入的任务注册;
其它4种输入任务的注册,注释掉,;
5、添加 触摸检测函数
还是在 “lv_port_indev.c” 中,
向下滚动到大约209行,找到触摸检测函数:touchpad_is_pressed(),
这个是:触屏状态检测函数,函数返回:0-未按下、1-按下;
第213行,原 return false, 注释掉;
第212行,原来是空行,插入:
tp_dev.scan(0);
if (tp_dev.sta & TP_PRES_DOWN) /* 触摸屏被按下 */
{
return true;
}
else
return false;
6、添加 坐标获取函数
还是在 “lv_port_indev.c” 中,

在刚才触摸检测函数的下方,找到坐标获取函数:touchpad_get_xy();
本函数的作为:使LVGL能够获取到触摸按下时的x、y坐标;
第221行, 修改为:
tp_dev.scan(0);
(*x) = tp_dev.x[0];
(*y) = tp_dev.y[0];

7、额外的测试预埋
在刚才的那个 touchpad_get_xy( ) 函数中,增加加一行画点操作:
222行下方,插入新行,画点操作:lcd_draw_point(x, y, BLACK);
这样操作的目的,是令LVGL在获取坐标时,也在这个坐标上画一个黑点

八、添加 LVGL 的文件引用

之前的几个部分,已修改完成了LVGL显示、触摸支持。
现在,正式在工程中“应用” LVGL。
1、给工程,添加 LVGL 的头文件
打开 main.c,在顶部, #include 三个头文件(复制下面三行):

#include “lvgl.h” // 它为整个LVGL提供了更完整的头文件引用
#include “lv_port_disp.h” // LVGL的显示支持
#include “lv_port_indev.h” // LVGL的触屏支持

2.初始化LCD、触摸屏
3、初始化LVGL、显示、触屏
在硬件的初始化代码之后,进行LVGL的初始化(复制下面3行):

lv_init(); // LVGL 初始化
lv_port_disp_init(); // 注册LVGL的显示任务
lv_port_indev_init(); // 注册LVGL的触屏检测任务

4、显示按钮控件、文本控件
在LVGL的初始化之后,添加LVGL控件 ,以测试LVGL的显示:

添加一个按钮

为按钮添加文本

添加一个独立的标签文本

    // 按钮
    lv_obj_t *myBtn = lv_btn_create(lv_scr_act());                               // 创建按钮; 父对象:当前活动屏幕
    lv_obj_set_pos(myBtn, 10, 10);                                               // 设置坐标
    lv_obj_set_size(myBtn, 120, 50);                                             // 设置大小

    // 按钮上的文本
    lv_obj_t *label_btn = lv_label_create(myBtn);                                // 创建文本标签,父对象:上面的btn按钮
    lv_obj_align(label_btn, LV_ALIGN_CENTER, 0, 0);                              // 对齐于:父对象
    lv_label_set_text(label_btn, "Test");                                        // 设置标签的文本

    // 独立的标签
    lv_obj_t *myLabel = lv_label_create(lv_scr_act());                           // 创建文本标签; 父对象:当前活动屏幕
    lv_label_set_text(myLabel, "Hello world!");                                  // 设置标签的文本
    lv_obj_align(myLabel, LV_ALIGN_CENTER, 0, 0);                                // 对齐于:父对象
    lv_obj_align_to(myBtn, myLabel, LV_ALIGN_OUT_TOP_MID, 0, -20);               // 对齐于:某对象

Program Size: Code=226890 RO-data=31090 RW-data=676 ZI-data=68388
FLASH 占用 = Code + RO-data + RW-data =226890+31090+676=258656=252KB
RAM 占用 = RW-data + ZI-data =676+68388=69064=67KB

九、LVGL 心跳、任务刷新

根据官方移植文档的要求,我们还要处理两个关于时间的问题:

间隔精准地,调用时基函数:lv_tick_inc(),俗称心跳,让LVGL精准地知道时间的流逝;

间隔5ms左右,调用周期性任务函数:lv_timer_handler() ,它的作用是检查所有注册任务的时间戳,执行那些已经到期的任务,如:屏显更新、动画更新、触控、定时器事件等;

1、给LVGL一个心跳时基

LVGL心跳函数(时基函数):lv_tick_inc(),每隔1ms调用一次;

这个函数对于图形界面的流畅运行比较重要,它令 LVGL 知道执行任务时流逝的时间。

如果 lv_tick_inc() 调用间隔不准确,可能会导致显示卡顿、任务处理不及时。

特别地,不建议使用滴答时钟SysTick产生这个时基,因为它常常需要被用于RTOS等。

建议使用TIM产生1ms中断,设置它的中断为高优先级,通过中断函数调用LVGL心跳时基。

可以使用TIM6产生1ms中断
2、每隔5ms左右,调用任务刷新函数:lv_timer_handler()
这个函数的作用:让LVGL检查所有已注册任务的时间戳,执行那些已经到期的任务,如刷屏、检测触摸等;
官方描述:大约5ms左右、在while循环中调用;
在main.c的while中,每隔5ms调用:lv_timer_handler()

十、移植成功

触摸、显示正常
在这里插入图片描述

十一、控件事件的添加和相应处理

LVGL的学习,可以大概地为分两部分:界面绘制、事件处理。

1、界面的绘制
因为LVGL的界面绘制,更常规的操作:使用可视化工具进行设计,再把界面工程移植回STM32。
2、事件处理
可视化工具,能帮我们处理好:控件生成、布局、屏幕切换等;
但是,不能处理STM32上的事,如按下按钮,发送某CAN通信等;
这些,都是需要回到Keil或者CubeIDE里,自行增加编写的。
示范:事件的添加、编写响应处理函数。
以按钮的点击为例,示范:事件添加、响应处理。
回到main函数,在添加按钮的那三行代码下方,增加一行,为控件添加事件:
lv_obj_add_event_cb(myBtn, myBtn_event, LV_EVENT_CLICKED, NULL);
myBtn:控件的名称(不限于按钮);
myBtn_event:事件响应时,LVGL调用的处理函数 (等一会儿要手动编写这个函数);
LV_EVENT_CLICKED:点击事件; 不同的控件,有不同的事件类型;
NULL:传递给回调函数的可选用户数据,这里暂时不用;
然后,开始编写刚才说的那个事件回调函数。
在main函数的上方,编写回调函数:myBtn_event();

// 按钮的事件回调函数
static void myBtn_event(lv_event_t *event)
{
    lv_obj_t *btn = lv_event_get_target(event);                    // 获得调用这个回调函数的对象
    if (event->code == LV_EVENT_CLICKED)
    {
        static uint8_t cnt = 0;
        cnt++;
        lv_obj_t *label = lv_obj_get_child(btn, NULL);             // 获取第1个子对象(我们在设计时,已安排了它的第1个子对象是一个label对象)
        lv_label_set_text_fmt(label, "Button: %d", cnt);           // 设置标签的文本,写法类似printf
    }
}

在这里插入图片描述

十二、显示中文

如何显示中文呢?如果使用代码的方法,不外乎两个方法:
LVGL源文件中,自带了一个中文字库。
网上有各种的字模转换方法、程序。

在这里插入图片描述

移植实现点击按钮控制LED1

LVGL按钮控制LED

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

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

相关文章

latex中Function函数报错

latex写伪码时,发现报错,截图如下: 解决办法,添加宏包,截图如下: \usepackage{algpseudocode}

虚幻引擎 C++ 实现平面阴影

1、平面阴影介绍 平面阴影是一种相对简单的渲染阴影的方式,可以理解为对一个模型渲染两次,一次是渲染模型本身,另一次是渲染模型的投影。渲染投影可以看作是将模型的顶点变换到地面的投影空间再渲染,可以理解为渲染了一个“压扁”…

pytorch学习笔记6 tensor拼接和拆分

cat 合并 dim必须首选相同(上例都是3),其次除了合并的dim(上例中为dim0)外,其它dim的size必须相同(dim 1的size是32,dim2的size是8),否则需要手动处理到相同…

vue3 + Spingboot + oracle 通过Base64存储图片

一 、前言 近期在做vue3 Springboot oracle 的工作&#xff0c;有个小功能通过页面导入图片保存到oracle数据库中&#xff0c;本人对前端不是很熟悉&#xff0c;借此记录一下实现方法&#xff1b; 二、前端部分代码 <template><div class"dialog-mian"&…

SQL注入实例(sqli-labs/less-7)

0、初始页面 1、确定闭合字符 确定闭合字符为单引号括号括号 )) ?id1 and 11 ?id1 and 12 ?id1 ?id1)) 2、查看securie_file_priv参数 ?id1)) and upddatexml(1,concat(0x7e,(select secure_file_priv),0x7e),1) -- 3、写入一句话木马 ?id1)) union select null,&q…

SFT、RLHF、DPO、IFT —— LLM 微调的进化之路

TL;DR • SFT、RLHF 和 DPO 都是先估计 LLMs 本身的偏好&#xff0c;再与人类的偏好进行对齐&#xff1b; • SFT 只通过 LLMs 生成的下一个单词进行估计&#xff0c;而 RLHF 和 DPO 通过 LLMs 生成的完整句子进行估计&#xff0c;显然后者的估计会更准确&#xff1b; • 虽然…

壹连科技净利润增速放缓:毛利率清一色下滑,研发费用率远弱同行

《港湾商业观察》施子夫 王璐 从2022年6月20日递表创业板以来&#xff0c;深圳壹连科技股份有限公司&#xff08;以下简称&#xff0c;壹连科技&#xff09;已经走了2年多的历程&#xff0c;如今离挂牌上市近在咫尺。 今年7月22日&#xff0c;壹连科技提交了注册申请。8月2日…

哪个电脑桌面便签好用并且无广告弹窗?

在日常生活和工作中&#xff0c;很多人喜欢在电脑桌面上使用便签软件。便签软件可以方便地记录临时任务、重要信息或者待办事项&#xff0c;帮助用户更好地管理时间和提高工作效率。想象一下&#xff0c;在繁忙的工作中&#xff0c;你能够快速在桌面便签上记下即将要做的任务&a…

基本K8s搭建Jekins+gitee项目自动部署

这里写目录标题 1.基本K8s部署安装Jekins2.设置Jenkins国内镜像源2.安装Gitee插件1.安装Gitee Plugin2.验证安装Gitee Plugin 3.新建任务1.输入任务名称2.输入你gitee上的项目链接3.测试构建 4.查看项目在k8s集群master节点的位置1.确认 Jenkins Pod 名称2.使用kubectl exec到 …

大数据技术复习--概述

概述 数据的概念&#xff1a;数据是指对客观事件进行记录并可以鉴别的符号&#xff0c;是对客观事物的性质、状态以及相互关系等进行记载的物理符号或这些物理符号的组合&#xff0c;是可识别的、抽象的符号。 数据类型&#xff1a;文本、图片、音频、视频 从数据的结构化程…

2024华数杯全国大学生数学建模竞赛B题思路-VLSI电路单元的自动布局-MIA 感知的详细布局问题描述

本章主要对超大规模集成电路&#xff08;Very Large Scale Integration Circuit&#xff0c;VLSI&#xff09;布局 问题进行了描述&#xff0c;首先简单梳理一下超大规模集成电路设计流程、物理设计相关的知 识&#xff0c;接着对 MIA 感知的混合高度单元集成电路详细布局问题的…

vue之ref 属性

文章目录 1.ref 属性概述1.1 作用和特点 2.vue2用法2.1 获取 dom2.3 获取组件&#xff1a; 3.vue3用法 1.ref 属性概述 1.1 作用和特点 &#xff08;1&#xff09;作用&#xff1a;用来给元素或组件注册引用信息(相当于是id的替代者) &#xff08;2&#xff09;应用在HTML标签…

Kettle下载安装MySQL驱动教程

在 Windows 系统上下载适用于 MySQL 的 JDBC 驱动程序&#xff0c;您可以按照以下步骤操作&#xff1a; 1. 访问 MySQL 官方下载页面 打开浏览器&#xff1a; 打开您喜欢的浏览器。 访问 MySQL Connector/J 下载页面&#xff1a; 访问 MySQL Connector/J 下载页面. 2. 选择…

探索亚马逊Amazon S3:无缝存储管理与极速数据传输的奥秘

亚马逊云科技中Amazon S3&#xff0c;因其设计简单与高度可靠&#xff0c;允许用户通过互联网存储和检索任意数量的数据&#xff0c;并能够自动扩展以满足各种规模的需求&#xff0c;使得Amazon S3成为了许多云计算应用和网站的核心存储基础设施之一&#xff0c;Amazon S3提供的…

WSL2安装多个Ubuntu实例,大佬带你玩转Linux!!!

安装wsl子系统并安装一个Ubuntuwsl ubuntu 安装的正确方式-CSDN博客文章浏览阅读546次,点赞10次,收藏4次。wsl ubuntu 安装的正确方式:将wsl2设置为默认版本:1、打开powershell2、设置wsl的版本为2​编辑3、更新wsl程序4、强制关闭子系统5、查看wsl支持的列表6、安装指定版…

【Dynamo】AnyCAD使用Dynamo绘制三维模型(二)——生成序列和范围的几种方式

说明&#xff1a; Dynamo为开源项目&#xff0c;开源地址&#xff1a;https://github.com/DynamoDS/Dynamo.git本文章使用版本&#xff1a;v3.0.3 范围 使用Range节点 start和end分别表示范围的边界&#xff0c;step表示步长。如下为[1,10]范围内步长为2结果 ​ 使用Code…

[000-01-025].第07节:WorkBench

我的后端学习大纲 我的Drools学习大纲 8. WorkBench 8.1 WorkBench简介: 1.WorkBench是KIE组件中的元素&#xff0c;也称为KIE-WB&#xff0c;是Drools-WB与JBPM-WB的结合体。它是一个可视化的规则编辑器。WorkBench其实就是一个war包&#xff0c;安装到tomcat中就可以运行。…

UE Sequence学习

UE4中的动画编辑器 —— Sequencer in UE4 - 知乎 (zhihu.com) UE4 LevelSequence源码解析 - 知乎 (zhihu.com) C模块 对ue4 sequence的学习和理解 - 知乎 (zhihu.com) 必须要先在你项目工程的.build.cs里加入 MoviePlayer, LevelSequence, MovieScene. 引入头文件 #inclu…

我所理解的sprd-camera摄像头框架流程分析

摄像头的图像格式:RGB24,RGB565,RGB444,YUV4:2:2 RGB24 表示R、G、B ,3种基色都用8个二进制位表示,那么红色、绿色、蓝色各有256种,那么由这三种基色构成的颜色就是256X256X256=16,777,216种,约等于1677万。UV 和我们熟知的 RGB 类似,是一种颜色编码格式。 YUV 包含三…

sonatype私服配置与下载

文章目录 私服下载地址setting.xml配置java中pom.xml配置上传 私服 下载地址 地址&#xff1a;https://help.sonatype.com/en/download.html 百度网盘地址链接: https://pan.baidu.com/s/1_sjjHbXs27ya49SEcN9XNw 提取码: g56i 1.下载后解压得到两个文件 2.进入到nexus-3.…