LVGL9.2移植至正点原子阿波罗STM32F429
参考文献:LVGL 移植到 STM32 通法 (https://www.cnblogs.com/Huae/p/18621614)
工程文件:Github
前言
LVGL(Light and Versatile Graphics Library)是一个开源的图形库,旨在为嵌入式系统提供高效、灵活的图形用户界面(GUI)解决方案。它具有小巧的内存占用和高性能的渲染能力,支持多种硬件平台,包括单片机、DSP 和 ARM 处理器等。LVGL 支持丰富的控件(如按钮、标签、图标、滚动条等),并提供强大的主题、样式和动画功能,使得开发者能够轻松设计出美观且响应迅速的界面。此外,LVGL 还支持触摸屏、图形加速(如 DMA2D)、多线程等特性,非常适合用于嵌入式应用程序,如智能家居、工业控制、医疗设备等领域。
本文将介绍一下最新的LVGL9.2在正点原子阿波罗STMF429IGT6开发板上的移植。正点原子自己的移植教程还是几年前的8.2版本,LVGL在这个版本之后对很多API进行了优化和裁剪,导致正点原子的教程现在已经不是很好用了。但是万变不离其宗,LVGL的主架构没有变,只需要一点细微的改变就可以进行移植。
我使用的屏幕是正点原子7寸RGB屏,分辨率为1024 * 600.编译器为IAR EW 9.6
在开始之前,确保你有:
- 相关的外设
- 正点原子例程提供的一系列外设驱动
- LVGL9.2版本源码
- LVGL官方的文档:点击跳转
我个人认为LVGL官方的文档非常重要,而且它甚至是有完整的官方授权的中文版本的。大多数东西都可以在上面找到。
准备工作
拷贝外设驱动
将所有和显示屏、触摸屏、SDRAM等有关的外设驱动加入工程。换句话说,你的工程需要做到在没有LVGL的环境下也能够通过最基本的显示函数在屏幕上显示东西的状态。如果你的工程在没有LVGL的环境下都没法通过正点原子例程里提供的函数显示东西,那显然是没有办法继续的。
拷贝LVGL库至工程文件夹
LVGL下载并解压之后,文件夹根目录内会包含很多文件夹及文件。在不需要demo或例程的情况下,我们只需要用到其中的这些文件/文件夹:
- examples文件夹中的porting文件夹
- src文件夹
- lv_conf_template.h
- lvgl.h
在工程文件夹根目录创建一个lvgls文件夹:
然后:
- 创建一个子文件夹,名为lvgl
- 创建一个子文件夹,名为lvgl_app
- 将之前提到的lv_conf_template.h重命名为lv_conf.h,移动到lvgls文件夹的根目录
- 打开examples/porting文件夹,复制lv_port_disp_template.c、lv_port_disp_template.h、lv_port_indev_template.c、lv_port_indev_template.h四个文件到lvgls文件夹根目录,并且重命名四个文件,去掉"_template"。这是后面要用到的显示屏和触摸屏注册文件
- 把src文件夹和lvgl.h复制到lvgls/lvgl文件夹中
现在的lvgls文件夹是这样的:
lvgl文件夹:
添加LVGL库文件至工程
将以下文件全部添加进入工程(可以一股脑全部加,也可以按照原本的文件结构自己慢慢加):
- src文件夹中的所有c文件,除了:
- draw中的nxp、renesas、sdl
- drivers文件夹
- lv_port_disp.c和lv_port_indev.c
(千万别忘了src文件夹根目录下还有个lv_init.c)
然后,添加头文件目录,到src为止就可以.
我的添加完之后的工程结构长这个样子:
修改Stack和Heap大小
LVGL需要至少2KB的Stack和Heap。
代码修改
定时器
LVGL需要一个tick源来为其提供心跳,这里使用基本定时器TIM6完成,PSC为10-1,ARR为6000-1.在tim.c中添加如下的回调函数:
1 |
|
别忘了在定时器初始化时打开TIM6的Time base,让定时器开始工作。
lv_conf.h
启用宏:#if 1 /*Set it to "1" to enable content*/
检查以下关键信息:
/*Color depth: 1 (I1), 8 (L8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888)*/#define LV_COLOR_DEPTH 16
:颜色深度,默认为RGB565#define LV_MEM_SIZE (64U * 1024U) /*[bytes]*/
缓冲区大小
,默认64KB
其他的东西理论上你看不懂也没关系,可以暂时不动,日后可以对照着注释慢慢研究。
lv_port_disp.c
- 设置屏幕分辨率:
1 |
|
注意,这里必须根据自己使用的屏幕分辨率来设置!如果尺寸设置的比实际屏幕小会导致实际的图像占不满整个屏幕,如果设置的比实际大会导致花屏、撕裂或干脆无法显示
- 设置缓冲区
1 |
|
我这里设置的是单缓冲区,实际按照自己需求来就可以。如果不是干那些高刷新率的活,单缓冲足够用了。原例程提供了三个缓冲区方式,分别是单缓冲、双缓冲和全尺寸双缓冲,选择合适的一个之后注释掉其他的几个就可以。
- 显示设备初始化
1 |
|
在这里添加屏幕的初始化函数。
- 设置刷屏
1 |
|
用正点原子例程中的lcd_color_fill()函数替代原来默认的画点函数。
lv_port_indev.c
- 修改初始化函数,添加触摸屏的初始化函数
1 |
|
- 修改触摸屏按下的识别动作
1 |
|
- 修改坐标读取函数
1 |
|
main.c
初始化一系列外设,对于lvgl相关的头文件则要按顺序初始化:
1 |
|
在while(1)主循环中添加time_handler
1 |
|
到这里为止,可以加一点自己的测试代码,然后编译烧录,LVGL就能正常显示了。
如果碰到问题欢迎站内私信。