目录
概述
1 软硬件介绍
1.1 软件版本信息
1.2 ST7796-LCD
1.3 MCU IO与LCD PIN对应关系
2 认识LVGL
2.1 LVGL官网
2.2 LVGL库文件下载
3 移植LVGL
3.1 准备移植文件
3.2 添加lvgl库文件到项目
3.2.1 src下的文件
3.2.2 examples下的文件
3.2.3 配置文件路径
3.2.4 其他文件
3.3 Keil中的编译配置
3.4 lvgl&lcd驱动接口
3.5 刷新UI函数
4 LVGL测试程序
5 测试
源代码下载地址:
N32G45XVL-STB之移植LVGL(lvgl-8.2.0)资源-CSDN文库
概述
本文主要介绍在N32G45XVL-STB移植lvgl-8.2.0的详细步骤,包括加载文件的方法,文件目录的路径,修改和LCD驱动层相关的接口,keil中文件路径的配置方法和编译参数,还编写一个LVGL的案例,验证移植的代码是否可以正常运行。
1 软硬件介绍
1.1 软件版本信息
软硬件信息 | 版本信息 |
---|---|
MCU类型 | N32G457VEL7 |
Keil | MDK ARM 5.38 |
调试工具:DAP | CMSIS-DAP |
1.2 ST7796-LCD
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对应关系如下图所示
1.3 MCU IO与LCD PIN对应关系
N32G457VEL7 PIN引脚 | LCD PIN引脚 |
---|---|
PA.07 | MOSI |
PA.06 | MISO |
PA.05 | SCK |
PD.04 | CS |
PD.05 | RST |
PD.06 | RS |
2 认识LVGL
2.1 LVGL官网
LVGL是最流行的免费和开源嵌入式图形库,可为任何MCU, MPU和显示类型创建漂亮的UI。基于这个特点,其可以在一般的MCU上都能运行的,本文选取STM32F407芯片作为主控MCU,实现该UI库的移植。
官方网址:
https://lvgl.io/
登录网址后,可以看见如下页面,目前最新版本已经升级到 LVGL v8.4 and v9.1 are released!:
2.2 LVGL库文件下载
lvgl的源代码已经共享到github上,用户可以在网站上直接下载,下载地址如下:
https://github.com/lvgl/lvgl
打开链接可以看见如下页面:
笔者选择早期的v8.2版本作为移植对象,其下载链接如下:
https://github.com/lvgl/lvgl/releases/tag/v8.2.0
连接页面如下:
下载完成后打开代码库文件夹,核心文件如下:
3 移植LVGL
3.1 准备移植文件
解压下载的lvgl源代码包,然后将如下文件目录和文件copy到工程目录下。各个文件或者文件夹的内容接口如下:
lvgl-8.2.0文件内容 | 功能介绍 |
---|---|
examples | 和MCU相关的驱动接口和应用Demo |
src | lvgl的核心源码包 |
lvgl.h | 资源引用的头文件 |
lv_conf_template.h | 资源配置头文件 |
3.2 添加lvgl库文件到项目
3.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文件到
step-8: 添加该目录下所有的.c文件到 lvgl-8.2.0/src/gpu
lvgl-8.2.0\src\draw\sw
lvgl-8.2.0\src\draw\sdl
3.2.2 examples下的文件
examples下的文件主要包括和mcu相关的接口函数和应用范例。移植代码时,只需移植porting目录下的文件即可。
3.2.3 配置文件路径
3.2.4 其他文件
修改如下文件的名称,重新命名如下:
修改完成后:
Keil中lvgl的文件结构如下:
3.3 Keil中的编译配置
在keil中配置如下信息,其目的是避免编译lvgl源代码时,出现过多的warning
--diag_suppress=68 --diag_suppress=111 --diag_suppress=188 --diag_suppress=223 --diag_suppress=546 --diag_suppress=1295
3.4 lvgl&lcd驱动接口
在lv_port_disp_template.c文件中实现和LCD相关的驱动接口
/**
* @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)
{
}
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 * 12];
lv_disp_draw_buf_init(&draw_buf_dsc_1, buf_1, NULL, MY_DISP_HOR_RES * 12);
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 */
3.5 刷新UI函数
在main函数中调用 lv_task_handler();
4 LVGL测试程序
编写一个LVGL测试程序,实现表盘功能,其代码如下
源代码如下:
#include "lv_mainstart.h"
#include "lvgl.h"
#include <stdio.h>
/* 获取当前活动屏幕的宽高 */
#define scr_act_width() lv_obj_get_width(lv_scr_act())
#define scr_act_height() lv_obj_get_height(lv_scr_act())
void lv_mainstart(void)
{
lv_obj_t* meter = lv_meter_create(lv_scr_act()); /* 定义并创建仪表 */
lv_obj_set_width(meter, scr_act_height() * 0.6); /* 设置仪表宽度 */
lv_obj_set_height(meter, scr_act_height() * 0.6); /* 设置仪表高度 */
/* 设置仪表位置 */
lv_obj_center(meter);
/* 设置仪表刻度 */
lv_meter_scale_t* scale = lv_meter_add_scale(meter); /* 定义并添加刻度 */
/* 设置小刻度数量为 41,宽度为 1,长度为屏幕高度除以 80,颜色为灰色 */
lv_meter_set_scale_ticks(meter, scale, 41, 1, scr_act_height() / 80,
lv_palette_main(LV_PALETTE_GREY));
/* 设置主刻度的步长为 8,宽度为 1,长度为屏幕高度除以 60,颜色为黑色,
刻度与数值的间距为屏幕高度除以 30 */
lv_meter_set_scale_major_ticks( meter, scale, 8, 1, scr_act_height() / 60,
lv_color_black(), scr_act_height() / 30);
}
/* End of this file */
5 测试
编译代码,下载到板卡中运行如下:
板卡正面图片