你需要提前准备好,LCD的相关函数、电容触摸的相关函数和一个可以跑的工程
1.准备LVGL8.3的包
2.修改lv_conf_template.h为lv_conf.h,进入lv_conf.h,修改第15行#if 0为#if 1
3.将lvgl整个包放至工程该目录下:APGC_V1_0\Middlewares\LVGL\GUI\
当前目录结构如下图所示:
其中demos文件夹已被拷贝至APGC_V1_0\Middlewares\LVGL\GUI_APP
如下图所示
在Keil中的Manage Project Items中添加如下item
之后进入APGC_V1_0\Middlewares\LVGL\GUI\lvgl\examples\porting修改文件名称,将所有的_template都删掉,如下图所示:
在Application/LVGL_Port中添加APGC_V1_0\Middlewares\LVGL\GUI\lvgl\examples\porting中的显示与输入文件:
在Application/LVGL中添加的较多
APGC_V1_0\Middlewares\LVGL\GUI\lvgl\src\core中的全部.c文件
APGC_V1_0\Middlewares\LVGL\GUI\lvgl\src\draw中除了arm2d、nxp、外的所有.c文件
APGC_V1_0\Middlewares\LVGL\GUI\lvgl\src\extra中的全部.c文件,包括子文件夹中的
APGC_V1_0\Middlewares\LVGL\GUI\lvgl\src\font中的全部.c文件
APGC_V1_0\Middlewares\LVGL\GUI\lvgl\src\hal中的全部.c文件
APGC_V1_0\Middlewares\LVGL\GUI\lvgl\src\misc中的全部.c文件
APGC_V1_0\Middlewares\LVGL\GUI\lvgl\src\widgets中的全部.c文件
在魔术棒中添加头文件目录:
在此页也勾选C99模式,在Misc栏输入:--diag_suppress=188,546,68,111屏蔽错误
添加如下四个头文件路径:
之后编译,应该是"APGC_V1_0\APGC_V1_0.axf" - 0 Error(s), 0 Warning(s).
打开lv_port_disp.c之后将#if 0改为#if 1、#include "lv_port_disp_template.h"改为include "lv_port_disp.h"
打开lv_port_disp.h之后将#if 0改为#if 1
打开lv_port_disp.c添加#include "ST7796S.h"屏幕驱动
在disp_init函数中添加屏幕初始化函数如下图
之后注释掉BUFF缓存的2和3
修改屏幕像素为自己的屏幕像素
在刷屏函数中修改为自己的刷新函数
在FreeRTOS.c中添加头文件
#include "lvgl.h" #include "lv_port_disp.h"
在主线程中写如下代码测试:
/* USER CODE END Header_StartDefaultTask */ void StartDefaultTask(void *argument) { /* USER CODE BEGIN StartDefaultTask */ /* Infinite loop */ lv_init(); lv_port_disp_init(); lv_obj_t* switch_obj = lv_switch_create(lv_scr_act()); lv_obj_set_size(switch_obj,120,60); lv_obj_align(switch_obj,LV_ALIGN_CENTER,0,0); for(;;) { lv_timer_handler(); osDelay(5); } /* USER CODE END StartDefaultTask */ }
有看过别人移植的人会问其他人都有另外一个函数lv_tick_inc();函数卸载定时器回调中,但此处没有,这是因为开了FreeRTOS,可以有其他方法来写,打开lv_conf.h文件,找到LV_TICK_CUSTOM这个宏,修改如下
/*Use a custom tick source that tells the elapsed time in milliseconds. *It removes the need to manually update the tick with `lv_tick_inc()`)*/ #define LV_TICK_CUSTOM 1 #if LV_TICK_CUSTOM #define LV_TICK_CUSTOM_INCLUDE "FreeRTOS.h" /*Header for the system time function*/ #define LV_TICK_CUSTOM_SYS_TIME_EXPR (xTaskGetTickCount()) /*Expression evaluating to current system time in ms*/ #endif /*LV_TICK_CUSTOM*/
此时下载代码即可观察到屏幕上有一个按钮,如下:
之后便是触摸的移植。
打开lv_port_indev.c之后将#if 0改为#if 1、#include "lv_port_indev_template.h"改为include "lv_port_disp.h"
打开lv_port_indev.h之后将#if 0改为#if 1
打开lv_port_indev.c添加#include "GT911.h"触摸驱动
在lv_port_indev.c文件中将除了触摸屏之外的注释掉:
从这里开始注释
一直注释到最后一个花括号停下
同理从这里继续开始注释
一直注释到最后一个#else停止
这样就把多余的输入设备删掉了
之后在初始化函数中添加自己的触摸屏初始化代码,如下:
/*Initialize your touchpad*/ static void touchpad_init(void) { QF_CTP_Init(); /*Your code comes here*/ }
定义当前触摸屏是否按下函数:
/*Return true is the touchpad is pressed*/ static bool touchpad_is_pressed(void) { /*Your code comes here*/ return QF_CTP_GetEnable();; }
之后再定义获取坐标函数:
/*Get the x and y coordinates if the touchpad is pressed*/ static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y) { /*Your code comes here*/ uint16_t PosX,PosY; QF_CTP_GetPos(&PosX,&PosY); (*x) = PosX; (*y) = PosY; }
之后如同显示部分一样将触摸的头文件#include "lv_port_indev.h"也加到FreeRTOS.c中,此时的主线程变成了如下
/* USER CODE END Header_StartDefaultTask */ void StartDefaultTask(void *argument) { /* USER CODE BEGIN StartDefaultTask */ /* Infinite loop */ lv_init(); lv_port_disp_init(); lv_port_indev_init(); lv_obj_t* switch_obj = lv_switch_create(lv_scr_act()); lv_obj_set_size(switch_obj,120,60); lv_obj_align(switch_obj,LV_ALIGN_CENTER,0,0); for(;;) { lv_timer_handler(); osDelay(5); } /* USER CODE END StartDefaultTask */ }
此时编译,应该也是"APGC_V1_0\APGC_V1_0.axf" - 0 Error(s), 0 Warning(s).
下载到开发板,点击开关即可发现可以切换开关状态了,切换之后如下图:
至此LVGL已完全移植,之后就是相关demo的测试。
此处只演示一个music的demo测试,在Keil中的Manage Project Items中新建Application/LVGL_APP,并且将APGC_V1_0\Middlewares\LVGL\GUI_APP\demos\music目录地下的lv_demo_music.c、lv_demo_music_list.c、lv_demo_music_main.c添加进来,还有assets目录下的所有.c文件。
之后在魔术棒中添加头文件路径:
APGC_V1_0\Middlewares\LVGL\GUI_APP\demos
APGC_V1_0\Middlewares\LVGL\GUI_APP\demos\music
打开lv_conf.h文件,找到如下部分并改为:
/*Music player demo*/ #define LV_USE_DEMO_MUSIC 1 #if LV_USE_DEMO_MUSIC #define LV_DEMO_MUSIC_SQUARE 0 #define LV_DEMO_MUSIC_LANDSCAPE 0 #define LV_DEMO_MUSIC_ROUND 0 #define LV_DEMO_MUSIC_LARGE 0 #define LV_DEMO_MUSIC_AUTO_PLAY 0 #endif
之后在FreeRTOS.c中添加头文件#include "lv_demo_music.h",此时主函数变为如下:
/* USER CODE END Header_StartDefaultTask */ void StartDefaultTask(void *argument) { /* USER CODE BEGIN StartDefaultTask */ /* Infinite loop */ lv_init(); lv_port_disp_init(); lv_port_indev_init(); lv_demo_music(); for(;;) { lv_timer_handler(); osDelay(5); } /* USER CODE END StartDefaultTask */ }
此时编译应该会报错,提示某些字体找不到,
此时打开lv_conf.h文件找到如下代码
将#define LV_FONT_MONTSERRAT_12、#define LV_FONT_MONTSERRAT_16后面的0都改为1,再次编译。
注意,如果使用FreeRTOS,注意默认线程的大小,否则跑MUSIC这个DEMO的时候会出现进入HardFault_Handler的错误
最后的效果如下:
如果要问右下角的帧率怎么打开,那就去lv_conf.h中寻找#define LV_USE_PERF_MONITOR这句话吧
演示视频
文件系统等到之后再移植