stm32F407移植LVGL+GUI
前期准备
- 我现在使用的开发板是STM32F407ZGT6.
- 从网站上下载LVGL。官方网址:https://github.com/lvgl/lvgl,我在这次移植过程中使用的版本为v8.2。(建议使用相同版本的,在后面如果版本不匹配的话,会出现各种问题,所以建议使用和我一样的版本)
- 移植之前,准备好LCD显示实验、触摸屏实验、基本定时器实验、内存管理实验。(这里使用的所有文件都是正点原子的例程代码)
- 我们以内存管理实现为基础,向其添加其他文件所用的相关代码。并编译后,没有报错的话,开始正式移植。
移植LVGL
1、准备LVGL源码
1、当你从上述网址中下载了LVGL的源码后,你会得到一个压缩包,解压后会得到一个如图所示的文件夹。
2、将上图中的lv_conf_template.h 文件改名为 lv_conf.h。然后打开这个文件,在最开始的地方,找到下面的代码,并按下面的要求修改。
1 | 修改前: |
3、删除一些我们不要的文件。
在lvgl-8.2.0目录下的文件,除了demos、examples、src、lv_conf.h、lvgl.h,其他文件全部删除。最后的结果如图
然后打开文件examples,将其中的文件除了porting,其他全部删除。结果如图。
2、裸机移植LVGL
打开内存管理实验文件夹,没有移植之前的工程目录大概如下。
我们在其中新建一些文件夹,用来存放我们要移植的代码,从Middlewares开始创建,内容如图.
创建完成后,我们可以把处理好的LVGL中的文件examples、src、lv_conf.h、lvgl.h这四个复制到Middlewares/LVGL/GUI/lvgl目录下。结果如图
打开内存管理的工程,进入到keil界面的操作。
点击图中红色方框。
进入到下图这个界面按照图中创建分组,并添加相关的代码。(请注意,添加的代码比较烦,所以一定要注意)
添加相关的头文件路径(按照图中自上而下顺序操作)
开启C99模式
然后编译一下,如果报错了,请检查一下,文件是否添加进来了,头文件路径是否正确。如果正常没有报错,但是会有一些报错。不必理会。
修改代码
1、为LVGL提供时基。
打开我们工程中的timer.c。在头部添加LVGL的头文件。
1 | #include "lvgl.h" |
在中断中添加lvgl的心跳函数。
1 | //定时器3中断服务函数 |
上述源码中,定时器中断回调函数调用了 LVGL 的 lv_tick_inc 函数,该函数可以让 LVGL内部的时基参数加 1 (入口参数为 1 的情况下), 这里要注意,你定时器设置多少毫秒进入一次中断,那么, lv_tick_inc();函数的入口参数就设置为多少,不然时基就不准确。
接下来打开main.c文件,在mian函数中添加初始化。
1 | TIM3_Int_Init(999,167); |
2、配置显示屏、触摸输入驱动。
打开 Middlewares/lvgl/examples/porting 分组中的 lv_port_disp_template.c/h(显示屏相关)和 lv_port_indev_template.c/h (触摸输入相关)文件,将这 4 个文件中的条件编译指令 #if 0 都修改成#if 1 ,如下源码所示:
1 | 修改前: |
1、修改lv_port_disp_template.c文件。(基本按照图中改好,可能跟下面的截图不同,以下为准,因为这是我添加别的功能,修改了代码)
添加lcd的头文件,我们要使用lcd显示界面。
1
#include "lcd.h"
配置屏幕的分辨率。我是用的3.5存的TFTLCD屏幕,代码如下
1
2#define MY_DISP_HOR_RES 320 /* 屏幕宽度 */
#define MY_DISP_VER_RES 480 /* 屏幕高度 */在lv_port_disp_init函数中,按照图片注释下面的,保留上面的。初始化缓冲区,我们默认使用单行缓冲区。
修改分辨率。
在disp_init函数中,添加LCD的初始化。
配置花点函数,这个函数在lcd.h中可以找到。
2、修改lv_port_indev_template.c文件
添加头文件
注销处理显示屏之外的东西
触摸屏初始化
1
2
3
4
5
6
7
8
9
10
11
12
13
14static void touchpad_init(void)
{
/*Your code comes here*/
tp_dev . init ();
/* 电阻屏坐标矫正 */
if (KEY_Scan( 0 ) == KEY0_PRES) /* KEY0 按下 , 则执行校准程序 */
{
LCD_Clear(WHITE); /* 清屏 */
TP_Adjust(); /* 屏幕校准 */
TP_Save_Adjdata();
}
//TP_Init();
}检测屏幕是否被按下,
1
2
3
4
5
6
7
8
9/*Return true is the touchpad is pressed*/
static bool touchpad_is_pressed(void)
{
/*Your code comes here*/
tp_dev.scan(0);
if(tp_dev.sta & TP_PRES_DOWN)
return true;
return false;
}返回按下的坐标
1
2
3
4
5
6
7static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y)
{
/*Your code comes here*/
(*x) = tp_dev.x[0];
(*y) = tp_dev.y[0];
}
3、修改main.c文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "key.h"
#include "malloc.h"
#include "timer.h"
#include "sram.h"
/* LVGL */
#include "lvgl.h"
#include "lv_port_indev_template.h"
#include "lv_port_disp_template.h"
#include "lv_demo_stress.h"
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
delay_init(168);
uart_init(115200);
LED_Init();
LCD_Init();
KEY_Init();
TIM3_Int_Init(999,167);
lv_init();
lv_port_disp_init();
lv_port_indev_init();
lv_obj_t *label = lv_label_create(lv_scr_act());
lv_label_set_text(label,"Hello KUrumi!!!");
lv_obj_center(label);/
while(1)
{
lv_task_handler();
delay_ms(5);
}
}然后你会在屏幕上看到相对应的字符串。说明移植成功。
移植GUI
1、首先你要下载一个软件,GUI-Guider工具,提供了界面设计和代码生成的功能,使用这个工具能够让我们很快的设计好一个界面。(注意:你所下载的版本最好和LVGL的版本所匹配,GUI是基于LVGL的一个工具。)
2、下载后,打开软件,你会看到下面这个界面。点击创建新建项目。
3、然后你会进入一个选择LVGL版本的界面,如图,选择你项目中使用的版本号。前面使用的v8.2,所以我们选择v8.2。点击下一步。
跳转到下面的界面,双击simulator(模拟器),这一步是选择空白的模拟器。再点击下一步。
进入到了Templates模板界面中,我们选择EmptyUI。
进入带项目配置信息界面。再右侧输入栏中。我们先填写项目的名称,例如我们输入xianshi。下面是工程的路径,最后生成的代码也在这。在下面是面板类型,我们在下拉菜单中选择Custom…,下面出现新的一行,我们依次输入LCD,宽度:320;高度:480。输入完成后,点击创建。
然后进入到了下面的界面,你就可以创建你的界面了。
下面编辑界面我就不讲解了,讲起来比较麻烦,截图太多。下面我讲解你设计好界面后如何生成代码,如何加入到工程中。
插一句:如果你设计好了界面,想看看效果,GUI提供了模拟器,可以查看,点击图中绿色的按钮,选择C,就可以模拟。但是有一个前提,就是要在你的电脑上安装Java环境,才能用模拟器。
如何导出代码。有两种办法。
你可以去你创建时的那个目录中寻找。
你可以直接在工具栏中选择工具-》代码导出-》路径选择桌面。
我用的第二种方法,在桌面上你可以看到两个文件夹,custom和generated。
复制这两个文件夹到我们工程目录的中 “移植gui\Middlewares\LVGL\GUI_APP\“目录中
打开工程,在keil添加分组,为分组中添加文件中所有的.c文件。再添加文件路径。
这样就成功把GUi生成的代码加入到了我们工程中了。
然后再修改mian.c中的内容。
添加头文件
1
2
3
4
#include "gui_guider.h"
#include "events_init.h"
#include "custom.h"添加全局变量
1
lv_ui guider_ui;
在mian函数中添加初始化。
1
2
3setup_ui(&guider_ui);
events_init(&guider_ui);
custom_init(&guider_ui);编译没有报错,你就可以在你的LCD屏幕上看到你设计的界面了。
如果编译报错,如下面这样,提示#include “lv_font.h”出错,找到guider_fonts.h文件,修改#include “lv_font.h”。修改完成后如下,或者你可直接找到lv_font.h文件,直接复制到generated文件夹中。
1
2..\Middlewares\LVGL\GUI_APP\generated\guider_fonts\guider_fonts.h(8): error: #5: cannot open source input file "lv_font.h": No such file or directory
#include "lv_font.h"1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#ifndef GUIDER_FONTS_H
#define GUIDER_FONTS_H
#ifdef __cplusplus
extern "C" {
#endif
#include "../../GUI/lvgl/src/font/lv_font.h"
#ifdef __cplusplus
}
#endif
#endif