LVGL 移植到 STM32 通法 ( 例:LVGL 9.2.2 到 STM32F429 )

news/2025/3/9 10:51:55/文章来源:https://www.cnblogs.com/Huae/p/18621614

 

心法:

以往看过很多的移植教程、在 Keil 里面添加很多的文件分组、进到 LVGL 源码文件夹,进进出出多级目录添加很多的源码文件、这个添加,那个不需要添加,着实吓人 + 劝退人。

 

1. Keil 里面的文件分组的 组织结构、取名对编译根本不重要,只是方便程序员管理文件。 不过要注意,需要把 。C文件添加 (实际就是让 Keil 记录该文件的路径) 到 Keil 工程,Keil 才会编译该源码文件,生成对应的 。O文件。

2. 其实把 LVGL 源码全添加进 Keil 编译也是没问题的、把  。C 文件编译成 。O 二进制文件,在链接阶段,链接器需要哪个。O文件自己拿去链接就行,对这方面感到疑惑的可以看 C/C++编译过程

对于各种工程绝大部分情况下、多余添加源码文件进编译是没问题的,不被调用的函数 链接器 不会使用 那个函数所在的 。O文件,影响只有增加编译时间、产生多一点的 。O文件占用电脑硬盘,编译出来的最终文件即烧录进 STM32 的那个文件保持不变。

极少数情况下,多添加文件进行编译会产生冲突,比如 STM32F429 的 FMC 和 FSMC 源文件,同时只能编译一个,这还可能是 库文件设计者 有意为之。

少添加原文件必定出问题,比如 undefine symbol。

 

材料准备:

1. 获取 LVGL 源码

建议电脑安装 TortoiseGit ,可以以图形界面方式使用 Git。

选择一个文件夹,右键点击 Git Clone , 输入 LVGL 源码链接 https://github.com/lvgl/lvgl.git,将LVGL 源码克隆到本地。

进到 LVGL 源码目录,如需回退源码到最新发布的版本,以图更稳定可靠,可右键选择 TortoiseGit--》 Switch/Checkout --》选择 Tag 。 往下拉选择最新的 Tag。 

 按需 取消勾选 Create New Brach。 

 LVGL 9.2.2 源码文件夹 如下图:

不管版本如何变,移植到 STM32 (用 Keil 编译) 时,src 文件夹和 源码根目录 下的 。h 。C 文件都一概先复制过去。

下图高亮的是本次移植用到的文件(夹)

2. STM32 触摸屏工程

 广告:如 野火的工程:( 野火的教程、代码风格真是好,SMT32 和 FreeRTOS 教会了我很多,感谢野火。)

可惜我当年不懂得,错买了正点的板子。所以呢,我这个列子用的是 正点原子 的板子 STM32F429,搭载的是 SPI 接口的 4.3 寸 MCU 电容式触摸屏。

吐槽:鉴于 教程信息密度、源码风格、PDF手册权限等问题,建议不买正点原子的东西。

 

文件路径 及工程结构

在 触摸屏 工程根目录下创建一个 lvgls 文件夹 ( 可以取名其它英文字母名 ),lvgls 包含 lvgl 和 lv_app 文件夹,

同理 这两个文件夹也可以取名其它英文字母名 。

lvgl 下的 demos、src 文件夹 直接原封不动从 lvgl 源码文件夹复制过来。

examples 文件夹也可以直接从 lvgl 源码文件夹原封不动复制过来,但实际只需要里面的 porting 文件夹,所以自己精简。

lvgl 源码文件夹根目录的 。C 。h文件一并复制过来。

lvgl 下的 lv_conf_template.h 复制到上一层目录,并改名为  lv_conf.h , 打开改名后的 lv_conf.h ,把 第一个 # if 0  改为 # if 1 从而使能文件,下文简称 使能文件。

文件中 #define LV_COLOR_DEPTH 16  是配置屏幕色彩深度、我的 LCD 屏幕是 RGB565 , 所以保持无需变更。

 将 lvgl / examples / porting 中选中的文件复制到 与 lv_conf.h 文件同一目录下,并把 template 字眼去掉。分别是 ( **disp )显示 设备和 (**indev )输入设备的接口。

 完成后  lvgls 文件夹下 :

 

Keil 工程:

根据 lvgl / src 下的文件夹 (左) 在 keil 中创建相应的分组 (右),并多加一个 LVGL_SRC  用于添加 lvgl /src 下的 。C 文件,本例子中是 lv_init.c 。

 

没有注明的话,src 文件夹包括 各级子文件夹 所有 。C文件都添加到 Keil 的相应分组中。

当然根据文章开头说的,不嫌麻烦可以一股脑添加完所有 。C文件进 Keil 编译。

draw 中不需要添加 nxp 、renesas 、sdl 文件夹,其他均添加。

drivers 文件夹 都不 添加

libs 一定要添加 bin_decoder , 实际操作我把 图里 框中的都加上了,其它都不加。

 

千万记得 lvgl / src 下面的 。C 文件也要添加进 Keil , 本例中加到 LVGL_SRC 分组,本例中是 lv_init.c 。

 把头文件路径加到 Keil : 深度只需要到 lvgl / src /core 这个级别。当然,手动添加头文件路径有点烦,

你可以先保存好 Keil 工程、关闭工程,用高级一点的文本编辑器打开 Keil 工程文件( .uvprojx 文件),所谓的高级一点为的是 能 设置、区分 Windows、Unix、Macintosh文件?结尾 ,

这么说只是为了更保险,一般编辑软件都可以。

工程文件中搜索 IncludePath 观察已有的 头文件路径信息,确定好该往这个位置加入新的头文件路径,即可复制我的路径去使用。如果你的 lvgl 文件位置和文件夹名称和我的一样,就可以啥也不改,直接黏贴。

..\lvgls;..\lvgls\lvgl;..\lvgls\lvgl\src;..\lvgls\lvgl\src\core;..\lvgls\lvgl\src\display;..\lvgls\lvgl\src\draw;..\lvgls\lvgl\src\drivers;..\lvgls\lvgl\src\font;..\lvgls\lvgl\src\indev;..\lvgls\lvgl\src\layouts;..\lvgls\lvgl\src\libs;..\lvgls\lvgl\src\misc;..\lvgls\lvgl\src\osal;..\lvgls\lvgl\src\others;..\lvgls\lvgl\src\stdlib;..\lvgls\lvgl\src\themes;..\lvgls\lvgl\src\tick;..\lvgls\lvgl\src\widgets;..\lvgls\lvgl\demos;..\lvgls\lvgl\demos\benchmark;..\lvgls\lvgl\demos\widgets;..\lvgls\lvgl\demos\scroll;..\lvgls\lvgl\demos\music

其实 Keil 中的文件分组也可以用这个套路快速添加,我添加的时候 修改两个工程文件,那个修改包含太多文字,就不贴出来了,大家还是多熟悉一下操作。

 

Keil 中再 创建 LVGL_PORTING 和 LVGL_DEMO 分组:

LVGL_PORTING 添加 lvgls 文件夹下的 。C 文件,把 lv_conf.h 也加进来便于修改。

LVGL_DEMO 添加  lvgl /demos  根目录下的 。C文件 ( 本例是 lv_demos.c) 以及 widgets 子文件夹下所有 。C文件,我们先跑 widgets 这个例子。

还想跑其他例子,就自己加相应例子文件, 实际我还加了 bechmark、scroll、music 例子的。

 给 Keil 添加头文件路径:

 

 

至此 文件添加工作完成。

 

修改代码:

涉及的文件:

 

改堆栈 大小 

启动文件 startup_stm32f429xx.s 改 stack 和 heap 大小, 都为 0x2000 ,即 8 K 

 

给 lvgl 加心跳

伴随 HAL_IncTick(); 所在位置,本例是 stm32f4xx_it.c  文件中:

 #include "lv_tick.h"

/****其它******/

void SysTick_Handler(void)
{
    HAL_IncTick();
    lv_tick_inc(1);
}

当然也可以 改为 选择在 定时器中断中 执行   lv_tick_inc(1); 。 

 

lv_confg.h 中 :

除了前述的 使能文件、适配 屏幕颜色深度外,还有使能 demo 的宏,本例跑 widgets 例子,所以使能:

 lv_port_disp.c 中:

使能文件后,添加需要的 屏幕头文件,我这里多加了 usart.h 是为了使用 printf 函数,在串口打印调试信息。

修改屏幕分辨率适配自己的屏幕。

 修改 lv_port_disp_init 函数,分配 内存,有三种分配方式,本例用了模板 的 Example 1 , 目前我的理解是 lvgl 将像素信息输出到这个内存空间,然后 STM32 从这个空间获取像素信息赋值给 屏幕显示。

比如  LVGL ——》该内存空间——》DMA2D 外设自动复制该空间的(像素)数据到 ——》 STM32另一个内存空间(通常是称为 显存 的内存空间,通常在 SDRAM 中分配)——》 LTDC 自动复制 显存中的(像素)数据到 ——》LCD屏幕。

本例中有 SDRAM 的,使用__attribute__ ((at( 0XC03E8000))) 分配到了 SDRAM 中,本例中SDRAM 开始的地址为 0XC0000000,之所以放到 0XC03E8000 是因为前面的空间可能被其他工程代码用作 LCD 的显存。

 

 修改 disp_flush 函数。这个得阅读 屏幕驱动函数了,就是找 在一个矩形空间填充彩色像素能用哪个函数,或者用绘制一个彩色点的函数一个个像素点绘制(会比较慢)。

其中  px_map 是指向像素数据的指针,目前我的理解是传入 屏幕驱动函数 如 LCD_Color_Fill  时,px_map 被强制转换成相应的类型,如本例的 (u16* ) 本质是与 屏幕颜色深度相关、

其次是与 LCD_Color_Fill 函数原型相关。

 

 lv_port_indev.c 中:

使能文件、添加必要的 触摸屏头文件如 #include "touch.h"

函数 lv_port_indev_init 中仅保留 touchpad 部分的代码,其他可以用 # if  0   及 #endif 编译宏失能。 

 修改 touchpad_is_pressed 和 touchpad_get_xy 函数 :

 

main.c 中:

引入头文件

#include "lvgl.h"
#include "lv_port_disp.h"
#include "lv_port_indev.h"
#include "lv_demos.h"
#include "lv_demo_widgets.hint main(void){    HAL_Init();                     //初始化HAL库   

mian 函数

int main(void)
{HAL_Init();                      //初始化HAL库   Stm32_Clock_Init(360,25,2,8);   //设置时钟,180Mhzdelay_init(180);                //初始化延时函数uart_init(115200);              //初始化USARTLED_Init();                     //初始化LED KEY_Init();                     //初始化按键SDRAM_Init();                   //初始化SDRAMLCD_Init();                     //初始化LCDtp_dev.init();                  //触摸屏初始化 #if 1LCD_Display_Dir(1);       // LCD 设为横屏tp_dev.touchtype = 1;   // 触摸屏 设为横屏
    lv_init();lv_port_disp_init();lv_port_indev_init();lv_demo_widgets();//lv_demo_scroll();//lv_demo_benchmark();//lv_demo_music();while (1){lv_timer_handler();HAL_Delay(5);}#endif 
}

 

设置 Keil 使用 C99 标准编译:

 

 

大功告成。

 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用CSS3写一个图片左右切换的弹性动画

要使用CSS3创建一个图片左右切换的弹性动画,你可以使用@keyframes来定义动画,并利用animation属性将其应用到元素上。以下是一个简单的示例,展示了如何实现这样的动画效果:HTML:<!DOCTYPE html> <html lang="en"> <head><meta charset=&quo…

使用html画一个音乐播放器的布局

以下是一个简单的音乐播放器布局示例,使用HTML和CSS实现: <!DOCTYPE html> <html> <head><title>音乐播放器</title><style>/* 样式设置 */body {font-family: Arial, sans-serif;background-color: #f4f4f4;margin: 0;padding: 0;}.pla…

散热器比较:东海X5 vs 利民AK120SE vs 玄冰500

目录起因测试环境关于测试记录塔体外观AIDA64烤机测试东海X5利民AK120SE玄冰500待机测试东海X5利民AK120SE玄冰500噪音(主管感受)总结 起因 升级电脑,找朋友弄来了淘汰的机箱电源主板啥的,加上自己淘汰的cpu显卡,配成另一台电脑作他用 风扇也放旧电脑用了,因此要买个新风…

3DGStream:3D飞行训练实现照片级逼真自由视点视频的高效流式传输

3DGStream:3D飞行训练实现照片级逼真自由视点视频的高效流式传输 5.13.1 3DGStream:3D飞行训练实现照片级逼真自由视点视频的高效流式传输概述 从多视图视频构建动态场景的逼真自由视点视频(FVV)仍然是一项具有挑战性的工作。尽管当前的神经渲染技术取得了显著进步,但这些…

利用协同嵌入模型超越多任务密集预测

利用协同嵌入模型超越多任务密集预测 5.7.1 利用协同嵌入模型超越多任务密集预测概述 多任务视觉场景理解旨在利用一组相关任务之间的关系,通过将它们嵌入到一个统一的网络中来同时解决这些问题。然而,从任务层面的角度来看,大多数现有方法都引起了两个主要问题:①不同任务…

事件流超分辨率的双边事件挖掘与互补

事件流超分辨率的双边事件挖掘与互补 5.6.1事件流超分辨率的双边事件挖掘与互补概述 事件流超分辨率(ESR)旨在解决事件流中空间分辨率不足的挑战,这对事件相机在复杂场景中的应用具有重要意义。以前的ESR工作通常以混合范式处理积极和消极事件。这种范式限制了他们有效地模拟…

两本书推荐《AI芯片开发核心技术详解》、《智能汽车传感器:原理设计应用》

两本书推荐《AI芯片开发核心技术详解》、《智能汽车传感器:原理设计应用》由清华大学出版社资深编辑赵佳霓老师策划编辑的新书《AI芯片开发核心技术详解》已经出版,京东、淘宝天猫、当当等网上,相应陆陆续续可以购买。该书强力解析AI芯片的核心技术开发,内容翔实、知识点新…

【甲方安全】金融行业+安全架构(三)

第一部分 安全架构第三章 安全规划3.1 规划前的思考3.2 规划框架3.3 制订步骤3.3.1 调研3.3.2 目标、现状和差距3.3.3 制订解决方案3.3.4 定稿3.3.5 上层汇报3.3.6 执行与回顾3.4 注意事项3.5 小结《企业安全建设指南 金融行业安全架构与技术实践》——聂君 李燕 何扬军 编著,…

【甲方安全】金融安全+安全架构(四)

第一部分 安全架构第四章 内控合规管理4.1 概述4.1.1 合规、内控、风险管理的关系4.1.2 目标及领域4.1.3 落地方法4.2 信息科技风险管理4.2.1 原则4.2.2 组织架构和职责4.2.3 管理内容4.2.4 管理手段和流程4.2.5 报告机制4.2.6 信息科技风险监控指标4.3 监督检查4.4 制度管理4.…

【企业安全】安全架构(四)

第一部分 安全架构第四章 内控合规管理4.1 概述4.1.1 合规、内控、风险管理的关系4.1.2 目标及领域4.1.3 落地方法4.2 信息科技风险管理4.2.1 原则4.2.2 组织架构和职责4.2.3 管理内容4.2.4 管理手段和流程4.2.5 报告机制4.2.6 信息科技风险监控指标4.3 监督检查4.4 制度管理4.…

渗透测试-前端加密分析之RSA响应加密

本文是高级前端加解密与验签实战的第7篇文章,本系列文章实验靶场为Yakit里自带的Vulinbox靶场,本文讲述的是绕过请求包和响应包加密来爆破登录界面。本文是高级前端加解密与验签实战的第7篇文章,本系列文章实验靶场为Yakit里自带的Vulinbox靶场,本文讲述的是绕过请求包和响…

【Flink系列】美团外卖实时数仓建设实践

一、实时技术及架构 二、业务痛点 三、数据特点与应用场景 四、实时数仓架构设计 五、基于Flink的实时数仓应用案例一、实时技术及架构 1.1 实时计算技术选型 目前,市面上已经开源的实时技术还是很多的,比较通用的有Spark Streaming、Flink等,技术同学在做选型时要根据公司的…