【CubeMX-HAL库】STM32H743—手把手教你LVGL移植
【CubeMX-HAL库】STM32H743—手把手教你LVGL移植
本文将详细介绍如何在STM32H743微控制器上移植LVGL(Light and Versatile Graphics Library)图形库。内容涵盖LVGL简介、移植准备、源码移植、工程准备、代码修改、问题解决以及模拟器移植等多个方面,适合有一定嵌入式系统开发基础的读者学习参考。
LVGL简介
本次基于STM32H743配置LVGL8.3.10,已使用CubeMX配置好LTDC与I2C实现屏幕的显示与触摸。基本上,每个能够驱动显示器的现代控制器都适合运行 LVGL。最低要求是:
- 处理器:16、32 或 64 位微控制器或处理器
- 时钟频率:建议使用 >16 MHz 时钟速度
- 闪存/ROM:> 64 kB 用于非常重要的组件 (> 建议使用 180 kB)
- RAM:
- 静态 RAM 使用量:~2 kB,取决于使用的功能和对象类型
- 堆: > 2kB (> 建议使用 8 kB)
- 动态数据(堆): > 2 KB (> 如果使用多个对象,建议使用 16 kB). 在 lv_conf.h 文件中配置 LV_MEM_SIZE 生效。
- 显示缓冲区:> “水平分辨率”像素(推荐 >10 × 10ד 水平分辨率”)
- MCU或外部显示控制器中的一个帧缓冲区
- 编译器:C99 或更新的编译器
移植准备
1. LVGL源码压缩包
GitHub - LVGL下载链接,可以下载对应需要的版本。
2. 屏幕画点函数
void ltdc_draw_point(uint16_t x,uint16_t y,uint16_t color)//画点
{
*(__IO uint16_t*)( SDRAM_BANK_ADDR + 2*(x + y*1024) ) = color ;//RGB565格式
}
3. 屏幕读点函数
uint16_t GT911_X,GT911_Y;//读点坐标
uint8_t GT9XX_Scan(void)//触摸扫描:返回值1->被按下,0->无按下
{
uint8_t mode = 0;
uint8_t i;
uint8_t buf[4];
/* 读取状态寄存器 */
GT9XX_RD_Reg(GT9XXX_GSTID_REG, &mode, 1);
if ((mode & 0x80) && ((mode & 0xF) <= 5))//有触摸并且小于5个点
{
i = 0;
GT9XX_WR_Reg(GT9XXX_GSTID_REG, &i, 1); /* 清楚标记 */
}
if ((mode & 0xF) && ((mode & 0xF) <= 5))
{
GT9XX_RD_Reg(GT9XXX_TP1_REG, buf, 4);
GT911_X = ((uint16_t)buf[1] << 8) + buf[0];
GT911_Y = ((uint16_t)buf[3] << 8) + buf[2];
return 1;
}
return 0;
}
一、LVGL源码移植
1. 首先解压LVGL源码的压缩包
2. 将LVGL文件进行裁剪
仅保留demos、examples、src、lv_conf_template.h、lvgl.h文件
3. 修改lv_conf.h文件
- 将lv_conf_template.h重命名为lv_conf.h
- 并将#if 0条件编译改为#if 1
二、工程准备
1. 通过CubeMX配置定时器时基
配置基本定时器TIM6为LVGL提供心跳,定时时间1ms
2. 新建存放LVGL的文件夹
CubeMX生成的工程中新建Middlewares文件夹后更新工程会被系统自动删除,所以直接新建LVGL文件夹。新建完LVGL文件夹后将裁剪好的LVGL源码复制到当前工程
3. 在Keil中进行文件夹分组命名
4. 添加LVGL相关.c文件到对应分组
①porting中添加 examples/porting文件夹下的lv_port_disp_template.c 和 lv_port_indev_template.c 文件
②src中添加lvgl/src文件夹中的文件(draw文件夹中其他芯片的源文件不用添加)
5. 添加头文件路径
屏蔽MDK警告(慎用,非必须),在配置界面 C/C++的 Misc Controls 栏中填入(不要有空格):
--diag_suppress=68,111,188,223,546,1295
文件使用UTF-8编码,防止后续写代码时出现错误,可以在配置界面C/C++的 Misc Controls 栏中填入:--locale=english 避免一些错误
--locale=english
三、移植代码修改
1. 屏幕显示输出配置
2. 输入设备配置
① 触摸输入设置
将触摸之外的部分注释掉
② 键盘输入设置
将其余不用的输入设备函数注释掉,修改对应的键盘设置初始化函数。在输入设备初始化函数的键盘外设部分可以看到有一行提示信息,键盘设备需要创建一个关系组,将创建的部件添加到关系组中才可以通过按键进行控制。
在main.c中声明输入设备结构体,在函数中创建组,并将组绑定到键盘输入设备,将创建的部件按添加到该组中,方可通过按键对部件的操作。
extern lv_indev_t * indev_keypad;//声明外部键盘输入设备结构体
lv_group_t *group=lv_group_create();//创建group组
lv_indev_set_group(indev_keypad,group);//将组绑定到键盘输入设备
lv_group_add_obj(group,switch_obj);//将部件添加到组中
3. 提供LVGL时基
HAL_TIM_Base_Start_IT(&htim6);//使能定时器驱动,提供LVGL时基
#include "lvgl.h"
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM6)
{
lv_tick_inc(1);//x为中断时间间隔(单位/ms)
}
}
4. 编写主函数代码
#include "lvgl.h"
#include "lv_port_disp_template.h"
#include "lv_port_indev_template.h"
lv_init();//LVGL初始化
lv_port_disp_init();//LVGL显示初始化
lv_port_indev_init();//LVGL输入设备初始化
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);
lv_timer_handler();
HAL_Delay(5);
5. 编译下载运行
四、问题解决
1. 修改栈大小
若报错空间不够或者程序下载之后显示不全,则修改栈大小从0x400改为0x800
2. 字库生成
Font Converter —LVGL
五、模拟器移植
Simulator on PC(PC上的模拟器)-LVGL官网master
Simulator on PC(PC上的模拟器)-LVGL官网8.3
Simulator on PC(PC上的模拟器)-百问网
本次以CodeBlocks 20.03mingw-setup版本移植为例:
CodeBlocks下载官网
CodeBlocks: Windows (简单方便推荐使用)-GitHub
老版本模拟器参考资料:
LVGL 模拟仿真(Windows+CodeBlocks)博客园
1. LVGL模拟器源码下载
打开CodeBlocks版本的LVGL下载链接可以看到整个目录文件,下载主安装包后还要注意带@的的文件夹还要双击打开后再次下载。
① 下载两个LVGL模拟器压缩包
② 解压两个压缩包
③ 将@文件移植到主文件lvgl目录下
2. 修改配置文件
① main.c
修改屏幕分辨率
② lv_conf.h
修改颜色格式
3. 编译运行
4. 报错解决
参考报错解决链接:1-4-1_windows PC模拟器(codeblock)运行LVGL
① MinGW编译器确定
② 编译器设置
否则可能弹出很多报错(正点原子的模拟器中则不需要修改这项,不过修改之后也能编译)
③ 工程构建选项中选C99模式
这个不一定需要,如果最后还编译不成功就试试。