目录
概述
1 认识LVGL
1.1 LVGL官网
1.2 LVGL库文件下载
2 认识SPI接口型LCD
2.1 PIN引脚定义
2.2 MCU IO与LCD PIN对应关系
3 实现LCD驱动
3.1 使用STM32Cube配置Project
3.2 STM32Cube生成工程
4 移植LVGL
4.1 准备移植文件
4.2 添加lvgl库文件到项目
4.2.1 src下的文件
4.2.2 examples下的文件
4.2.3 配置文件路径
4.2.4 其他文件
4.3 工程目录下的文件结构
4.4 Keil中的编译配置
4.5 lvgl&lcd驱动接口
5 测试代码
5.1 主函数
5.2 测试函数
6 系统测试
概述
本文主要介绍基于STM32移植lvgl(V8.2)的详细过程,包括lvgl源代码的下载过程,如何加载这些文件到keil中,以及需要需改的接口文件内容。笔者使用的LCD屏幕为SPI接口类型,通过实操的方法完整的移植lvgl到stm32f4平台,并能完整的运行lvgl的demo。
1 认识LVGL
1.1 LVGL官网
LVGL是最流行的免费和开源嵌入式图形库,可为任何MCU, MPU和显示类型创建漂亮的UI。基于这个特点,其可以在一般的MCU上都能运行的,本文选取STM32F407芯片作为主控MCU,实现该UI库的移植。
官方网址:
https://lvgl.io/
登录网址后,可以看见如下页面,目前最新版本已经升级到 LVGL v8.4 and v9.1 are released!:
1.2 LVGL库文件下载
lvgl的源代码已经共享到github上,用户可以在网站上直接下载,下载地址如下:
https://github.com/lvgl/lvgl
打开链接可以看见如下页面:
笔者选择早期的v8.2版本作为移植对象,其下载链接如下:
https://github.com/lvgl/lvgl/releases/tag/v8.2.0
连接页面如下:
下载完成后打开代码库文件夹,核心文件如下:
2 认识SPI接口型LCD
2.1 PIN引脚定义
LCD的PIN引脚功能介绍
序号 | 模块引脚 | 引脚说明 |
1 | VCC | 屏电源正 |
2 | GND | 屏电源地 |
3 | LCD_CS | 液晶屏片选控制信号,低电平有效 |
4 | LCD_RST | 液晶屏复位控制信号,低电平复位 |
5 | LCD_RS | 液晶屏命令/数据选择控制信号高电平:数据,低电平:命令 |
6 | SDI(MOSI) | SPI总线写数据信号(SD卡和液晶屏共用) |
7 | SCK | SPI总线时钟信号(SD卡和液晶屏共用) |
8 | LED | 液晶屏背光控制信号(如需要控制,请接引脚,如不需要控制,可以不接) |
9 | SDO(MISO) | SPI总线读数据信号(SD卡和液晶屏共用) |
10 | CTP_SCL | 电容触摸屏IIC总线时钟信号(无触摸屏的模块不需连接) |
11 | CTP_RST | 电容触摸屏复位控制信号,低电平复位(无触摸屏的模块不需连接) |
12 | CTP_SDA | 电容触摸屏IIC总线数据信号(无触摸屏的模块不需连接) |
13 | CTP_INT | 电容触摸屏IIC总线触摸中断信号,产生触摸时,输入低电平到主控(无触摸屏的模块不需连接) |
14 | SD_CS | SD卡片选控制信号,低电平有效(不使用SD卡功能,可不接) |
实体LCD Port对应关系如下图所示
2.2 MCU IO与LCD PIN对应关系
STM32 PIN引脚 | LCD PIN引脚 |
---|---|
PB5-MOSI | MOSI |
PB4-MISO | MISO |
PB3-SCK | SCK |
PB6 | CS |
PB9 | RST |
PB8 | RS |
3 实现LCD驱动
3.1 使用STM32Cube配置Project
1) 配置SPI接口
SPI的参数
2)配置LCD的控制引脚
3)使能外部晶振
3.2 STM32Cube生成工程
使用STM32Cube生成工程,并创建两个目录
User/lcd_drv 驱动文件目录
User/test 测试文件目录
LCD驱动代码的详尽情况,请参考笔者提供的源码,或者使用LCD的供应商提供的代码。
在移植LVGL库之前,必须保证LCD的驱动程序能够正确运行:
4 移植LVGL
4.1 准备移植文件
解压下载的lvgl源代码包,然后将如下文件目录和文件copy到工程目录下。各个文件或者文件夹的内容接口如下:
lvgl-8.2.0文件内容 | 功能介绍 |
---|---|
examples | 和MCU相关的驱动接口和应用Demo |
src | lvgl的核心源码包 |
lvgl.h | 资源引用的头文件 |
lv_conf_template.h | 资源配置头文件 |
4.2 添加lvgl库文件到项目
4.2.1 src下的文件
step-1: Core文件目录,添加该目录下所有的.c文件到
step-2: draw文件目录,添加该目录下所有的.c文件到
step-3: extra文件目录,添加该目录下所有的.c文件到
step-4: font文件目录,添加该目录下所有的.c文件到
step-5: hal文件目录,添加该目录下所有的.c文件到
step-6: misc文件目录,添加该目录下所有的.c文件到
step-7: widgets文件目录,添加该目录下所有的.c文件到
4.2.2 examples下的文件
examples下的文件主要包括和mcu相关的接口函数和应用范例。移植代码时,只需移植porting目录下的文件即可。
4.2.3 配置文件路径
在Keil中配置文件夹路径,方便文件引用
4.2.4 其他文件
修改如下文件的名称,重新命名如下:
4.3 工程目录下的文件结构
完成以上步骤后,在项目文件中已经加载了lvgl的源代码,具体内容如下:
Keil中lvgl的文件结构如下:
4.4 Keil中的编译配置
在keil中配置如下信息,其目的是避免编译lvgl源代码时,出现过多的warning
--diag_suppress=68 --diag_suppress=111 --diag_suppress=188 --diag_suppress=223 --diag_suppress=546 --diag_suppress=1295
4.5 lvgl&lcd驱动接口
在lv_port_disp_template.c文件中实现和LCD相关的驱动接口
step-1: 添加LCD驱动头文件
step-2: 修改lcd的相关参数
step-3: 初始化接口函数
通过以上步骤,移植工作全部结束,lv_port_disp_template.c文件的详细代码:
/*** @file lv_port_disp_templ.c**//* Includes ------------------------------------------------------------------*/
#include "lv_port_disp_template.h"
#include "lvgl.h"
#include "lcd_drv.h"/* Private includes ----------------------------------------------------------*/
#define MY_DISP_HOR_RES LCD_W
#define MY_DISP_VER_RES LCD_H /* Private function prototypes -----------------------------------------------*/
static void disp_init(void);
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);/* Private user code ---------------------------------------------------------*/
static void lcd_draw_fast_rgb_color(int16_t sx, int16_t sy,int16_t ex, int16_t ey, uint16_t *color)
{uint16_t w = ex-sx+1;uint16_t h = ey-sy+1;uint32_t draw_size = w * h;uint32_t i;LCD_SetWindows(sx, sy, w, h);// set point value for( i = 0; i < draw_size; i++){Lcd_WriteData_16Bit(color[i]);}
}static void disp_init(void)
{/*You code here*/lcd_gpio_init();LCD_Init();LCD_direction(USE_HORIZONTAL);LCD_Clear(WHITE);
}void lv_port_disp_init(void)
{disp_init();static lv_disp_draw_buf_t draw_buf_dsc_1;static lv_color_t buf_1[MY_DISP_HOR_RES * 10]; lv_disp_draw_buf_init(&draw_buf_dsc_1, buf_1, NULL, MY_DISP_HOR_RES * 10);static lv_disp_drv_t disp_drv; lv_disp_drv_init(&disp_drv);disp_drv.hor_res = MY_DISP_HOR_RES;disp_drv.ver_res = MY_DISP_VER_RES;disp_drv.flush_cb = disp_flush;disp_drv.draw_buf = &draw_buf_dsc_1;lv_disp_drv_register(&disp_drv);
}static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{lcd_draw_fast_rgb_color(area->x1, area->y1, area->x2, area->y2, (uint16_t *)color_p);lv_disp_flush_ready(disp_drv);
}/* END of this file */
5 测试代码
5.1 主函数
代码122行: 初始化lvgl
代码123行:初始化显示接口
代码124行:调用测试函数
代码130行:调用刷新函数
5.2 测试函数
编写函数实现滑块显示,详细代码参看笔者的附近代码
6 系统测试
编译代码然后下载代码至MCU,运行代码,其结果如下: