目录

1. 下载LVGL源代码

2. 平台

3. 导入到工程

3.1 配置头文件

3.2 src文件夹

4. 移植

4.1 显示接口部分

4.1.1 disp_init

4.1.2 lv_port_disp_init

4.1.3 disp_flush

4.2 IPA部分

4.2.1 lv_draw_gd32_ipa_init

4.2.2 lv_draw_gd32_ipa_blend_fill

4.2.3 lv_draw_gd32_ipa_blend_map

4.2.3 lv_gpu_gd32_ipa_wait_cb

4.3 tick

5. 初始化


LVGL是Light and Versatile Graphics Library(轻量级通用型图形库)的简称,遵循MIT开源许可协议。

LVGL的官网地址如下:

LVGL - Light and Versatile Embedded Graphics Library

LVGL中文资料:

http://lvgl.z.net

1. 下载LVGL源代码

源代码在Github上。

LVGL部分:

GitHub - lvgl/lvgl: Powerful and easy-to-use embedded GUI library with many widgets, advanced visual effects (opacity, antialiasing, animations) and low memory requirements (16K RAM, 64K Flash).https://github.com/lvgl/lvgl

驱动部分(这部分和外部驱动芯片有关,例如ST7565之类的,而GD32F450自带驱动,所以实际不需要):

GitHub - lvgl/lv_drivers: TFT and touch pad drivers for LVGL embedded GUI libraryhttps://github.com/lvgl/lv_drivers

2. 平台

平台1:

GD的开发板GD32450I_EVAL,即GD32GD32F450 + 4.3寸480x272。

编译环境是MDK + GCC。

平台2:

Visual Studio模拟器,下载地址:

GitHub - lvgl/lv_port_win_visual_studio: LVGL Windows Simulator Visual Studio Edition

Visual Studio的版本要求是2019版及以上,下载后打开工程LVGL.Simulator.sln,将默认的平台改为X64(根据自己的Windows配置修改),编译后可以运行看看效果。如果只用这个模拟器学习,可以不看后面的GD32F450的移植。

3. 导入到工程

3.1 配置头文件

根目录下的lv_conf_template.h和lvgl.h拷贝到工程中,并将lv_conf_template.h改名为lv_conf.h。

lv_conf.h是会随项目情况改动到的,放在项目相关的目录内,这里做个另外的lv_config.h,里面只是include真正的lv_config.h文件。而lvgl.h不会更改,而且和代码内的包含路径有关,可以保留在原来的相对路径内。

其中lv_config.h的内容:

#ifndef LV_CONF_H
#define LV_CONF_H#include "..\..\include.h"#endif

其中include.h中会include真正的配置文件。

把配置文件中的配置打开,默认有一个宏定义设置为0的,改成1。

3.2 src文件夹

把文件加入MDK的工程,draw文件夹里面还有一些文件夹,可以先不加,和平台移植有关。

4. 移植

draw文件夹中有部分代码和平台有关,这里拷贝分和平台有关的代码,例如stm32_dma2d这个文件夹并改名字为gd32_ipa,里面的文件名改为lv_gpu_gd323_ipa.c和lv_gpu_gd323_ipa.h,将所有的stm32和dma2d的字符串改为gd32和ipa。

搜索LV_USE_GPU_STM32_DMA2D,参照改一个LV_USE_GPU_GD32_IPA,将lv_gpu_gd323_ipa.c中的函数内有关STM32的部分删除。

4.1 显示接口部分

在之前下载的lvgl文件夹里面\examples\porting文件夹下有对应的硬件接口文件lv_port_disp_template.c和lv_port_disp_template.h。这个文件主要要实现函数disp_init、lv_port_disp_init和disp_flush。

4.1.1 disp_init

显示初始化,主要是硬件配置和TLI接口初始化。

要使用到SDRAM,初始化好TLI接口,并且定义好一个Layer。

定义指针变量pTFTBuf指向SDRAM,因为这里定义格式为RGB565,大小为TFT_WIDTH * TFT_HEIGHT * 2字节。

#define GUI_TFT_BUF_START               EXMC_SDRAM_ADDR0
#define GUI_TFT_BUF_LEN                 (TFT_WIDTH * TFT_HEIGHT * sizeof(lv_color_t))
uint16_t *pTFTBuf = (uint16_t *)GUI_TFT_BUF_START;

选择Layer 0作为显示层,初始化这个层。

    tliLayer_t layer;layer.alpha = 0xFF;layer.bufAddr = (uint32_t)pTFTBuf;layer.defalutColor = 0x000000FF;//0x00FFFFFF;layer.format = FORMAT_RGB565;layer.x = 0;layer.y = 0;layer.w = TFT_WIDTH;layer.h = TFT_HEIGHT;tliLayerInit(0, layer, 1);

4.1.2 lv_port_disp_init

这个函数里面需要选择1种显示缓冲,文件提供了3种方式的缓冲方式,方式1/2/3对应的刷新速度分别是慢/中/快,而RAM占用是少/中/多。这里选择方式3,分配的空间放在SDRAM中(这里注意,如果RAM不够会导致Hard Fault中断,我选择方式2会在第四次调用disp_flush后出错)。

#define GUI_DISP_BUF1_START             (GUI_TFT_BUF_START + GUI_TFT_BUF_LEN)
#define GUI_DISP_BUF1_LEN               GUI_TFT_BUF_LEN
#define GUI_DISP_BUF2_START             (GUI_DISP_BUF1_START + GUI_DISP_BUF1_LEN)
#define GUI_DISP_BUF2_LEN               GUI_TFT_BUF_LENstatic lv_disp_draw_buf_t draw_buf_dsc;
static lv_color_t *dispbuf_1 = (lv_color_t *)GUI_DISP_BUF1_START;
static lv_color_t *dispbuf_2 = (lv_color_t *)GUI_DISP_BUF2_START;lv_disp_draw_buf_init(&draw_buf_dsc, dispbuf_1, dispbuf_2, GUI_DISP_BUF1_LEN);   /*Initialize the display buffer*/

4.1.3 disp_flush

对于GD32F450的TLI来说,flush就是对Layer对应的buffer更新数据。

static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{/*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/int32_t x;int32_t y;uint16_t *pTFTBuf = (uint16_t *)GUI_TFT_BUF_START;//Printf("draw:(%d, %d) - (%d, %d)\n", area->x1, area->y1, area->x2, area->y2);for(y = area->y1; y <= area->y2; y++) {for(x = area->x1; x <= area->x2; x++) {/*Put a pixel to the display. For example:*//*put_px(x, y, *color_p)*/*(uint16_t *)(pTFTBuf + y * TFT_WIDTH + x) = (*color_p).full;color_p++;}}/*IMPORTANT!!!*Inform the graphics library that you are ready with the flushing*/lv_disp_flush_ready(disp_drv);
}

4.2 IPA部分

4.2.1 lv_draw_gd32_ipa_init

初始化ipa,并设置颜色模式。

void lv_draw_gd32_ipa_init(void)
{RCU_AHB1EN |= ((uint32_t)1 << 23);//IPA ResetRCU_AHB1RST |= ((uint32_t)1 << 23);RCU_AHB1RST &= ~((uint32_t)1 << 23);/*set output colour mode*/IPA_CTL |= ((uint32_t)1 << 2);IPA_DPCTL = LV_IPA_COLOR_FORMAT;
}

4.2.2 lv_draw_gd32_ipa_blend_fill

这个函数的作用是用指定的颜色刷新显存。函数原型:

static void lv_draw_gd32_ipa_blend_fill(lv_color_t * dest_buf, lv_coord_t dest_stride, const lv_area_t * fill_area, lv_color_t color)

参数含义:

dest_buf - 显存地址

dest_stride - 显存地址偏移量

fill_area - 填充的区域,长方形(x1,y1)- (x2,  y2)

color - 填充的颜色

static void lv_draw_gd32_ipa_blend_fill(lv_color_t * dest_buf, lv_coord_t dest_stride, const lv_area_t * fill_area,lv_color_t color)
{/*Simply fill an area*/int32_t area_w = lv_area_get_width(fill_area);int32_t area_h = lv_area_get_height(fill_area);invalidate_cache();IPA_CTL |= ((uint32_t)1 << 2);  //Stop IPAIPA_CTL &= ~((uint32_t)0x3 << 16);IPA_CTL |= ((uint32_t)0x3 << 16);    //Specific color fillIPA_DMADDR = (uint32_t)dest_buf;IPA_DPV = color.full;IPA_DLOFF = dest_stride - area_w;IPA_IMS = (area_w << 16) | (area_h << 0);IPA_CTL |= ((uint32_t)1 << 0);
}

4.2.3 lv_draw_gd32_ipa_blend_map

这个函数的作用是指定buffer更新显存。

static void lv_draw_gd32_ipa_blend_map(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride,const lv_color_t * src_buf, lv_coord_t src_stride, lv_opa_t opa)

参数含义:

dest_buf - 显存地址

dest_area - 填充的区域

dest_stride - 显存地址偏移量

src_buf - 源数据地址

dest_stride - 源数据地址偏移量

opa - alpha值

static void lv_draw_gd32_ipa_blend_map(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride,const lv_color_t * src_buf, lv_coord_t src_stride, lv_opa_t opa)
{/*Simple copy*/int32_t dest_w = lv_area_get_width(dest_area);int32_t dest_h = lv_area_get_height(dest_area);invalidate_cache();if(opa >= LV_OPA_MAX) {IPA_CTL |= ((uint32_t)1 << 2);  //Stop IPAIPA_CTL &= ~((uint32_t)0x3 << 16);IPA_CTL = ((uint32_t)0x0 << 16);    IPA_FPCTL = LV_IPA_COLOR_FORMAT;IPA_FMADDR = (uint32_t)src_buf;IPA_FLOFF = src_stride - dest_w;IPA_DMADDR = (uint32_t)dest_buf;IPA_DLOFF = dest_stride - dest_w;IPA_IMS = (dest_w << 16) | (dest_h << 0);IPA_CTL |= ((uint32_t)1 << 0); //Start IPA}else {IPA_CTL |= ((uint32_t)1 << 2);  //Stop IPAIPA_CTL &= ~((uint32_t)0x3 << 16);IPA_CTL |= ((uint32_t)0x2 << 16);  IPA_BPCTL = LV_IPA_COLOR_FORMAT;IPA_BMADDR = (uint32_t)dest_buf;IPA_BLOFF = dest_stride - dest_w;IPA_FPCTL = (uint32_t)LV_IPA_COLOR_FORMAT/*alpha mode 2, replace with foreground * alpha value*/| (2 << 16)/*alpha value*/| (opa << 24);IPA_FMADDR = (uint32_t)src_buf;IPA_FLOFF = src_stride - dest_w;IPA_DMADDR = (uint32_t)dest_buf;IPA_DLOFF = dest_stride - dest_w;IPA_IMS = (dest_w << 16) | (dest_h << 0);IPA_CTL |= ((uint32_t)1 << 0); //Start IPA}
}

4.2.3 lv_gpu_gd32_ipa_wait_cb

这个函数的作用是等待渲染结束。

void lv_gpu_gd32_ipa_wait_cb(lv_draw_ctx_t * draw_ctx)
{lv_disp_t * disp = _lv_refr_get_disp_refreshing();if(disp->driver && disp->driver->wait_cb) {while(IPA_CTL & 0x01) {disp->driver->wait_cb(disp->driver);}}else {while(IPA_CTL & 0x01);}lv_draw_sw_wait_for_finish(draw_ctx);
}

4.3 tick

LVGL 需要一个系统滴答来了解动画和其他任务(例如输入设备读取)所用的时间,所以需要在一个定时器中调用lv_tick_inc。

lv_tick_inc(TIMER_MS);

定时调用这个函数即可,实现方式可以随意,裸奔的方式可以在system tick中调用。

5. 初始化

在使用其他LVGL的API前必须调用lv_init(),然后调用lv_port_disp_init即可。

    lv_init();lv_port_disp_init();

这时候屏幕应该是没有显示(如果把pTFTBuf 的数据全部改成0xF800,即红色,可以看到屏幕为红色,LVGL并没有起作用)。

在非OS应用中,需要在主循环中添加lv_task_handler();而在OS应用中,应该是在一个任务循环中添加这个函数的调用。

这是屏幕会显示白屏,添加一段测试程序(在lv_port_disp_init()后添加即可)。

lv_obj_t *rect = lv_obj_create(lv_scr_act());
lv_obj_set_size(rect, LV_PCT(20), LV_PCT(20));
lv_obj_align(rect, LV_ALIGN_CENTER, 0, 0);

即画一个矩形。

模拟器显示效果:

LVGL学习笔记1 - 准备相关推荐

  1. 【LVGL学习笔记】(三)控件使用

    LVGL全程LittleVGL,是一个轻量化的,开源的,用于嵌入式GUI设计的图形库.并且配合LVGL模拟器,可以在电脑对界面进行编辑显示,测试通过后再移植进嵌入式设备中,实现高效的项目开发. LVG ...

  2. 【LVGL学习笔记】(五)使用SquareLine Studio设计UI

    LVGL全程LittleVGL,是一个轻量化的,开源的,用于嵌入式GUI设计的图形库.并且配合LVGL模拟器,可以在电脑对界面进行编辑显示,测试通过后再移植进嵌入式设备中,实现高效的项目开发. LVG ...

  3. LittleVGL(LVGL)学习笔记——PC 模拟器的安装和使用(CodeBlocks)

    目录 一.简介 1.LittleVGL 所支持的 IDE 软件种类: 2.需要的工具: 二.安装配置软件和环境 1.littleVGL 模拟器库 2.安装CodeBlocks 三.创建工程项目 四.配 ...

  4. LVGL学习笔记(二):从0到1移植LVGL8.1到STM32平台上(完结篇)

    目录 一:TFT-LCD屏触摸 二:STM32CubeMX配置 三:FT5206触摸芯片驱动代码移植 四:LVGL 移植 4.1 源码下载 4.2 代码移植 4.3 添加源码至工程 4.4 指定头文件 ...

  5. 【LVGL学习笔记】(二) 基础概念

    LVGL全程LittleVGL,是一个轻量化的,开源的,用于嵌入式GUI设计的图形库.并且配合LVGL模拟器,可以在电脑对界面进行编辑显示,测试通过后再移植进嵌入式设备中,实现高效的项目开发. LVG ...

  6. LVGL学习笔记19 - 下拉列表dropdown

    目录 1. Parts 1.1 按钮状态 1.2 列表状态 2. 设置 2.1 设置选项 2.2 设置方向 2.3 设置符号 2.4 设置字符串 2.5 手动打开或关闭列表 2.6 设置高亮效果 3. ...

  7. LVGL学习笔记 20 - 滚轮Roller

    目录 1. Parts 2. 设置 2.1 设置选项 2.2 设置可见行 2.3 设置选中项 3. 样式 3.1 设置选项之间的间隔 3.2设置滚动效果时间 3.3 设置选中项的字体 3.4 设置选中 ...

  8. LVGL学习笔记7 - GD32平台优化

    目录 1. 颜色深度 2. 更新disp_init 3. 更新disp_flush 4. 改为IPA更新数据 5. 死机问题 学习过程中发现GD32平台的显示效果不佳,而且会出现死机的问题,需要优化一 ...

  9. LVGL学习笔记14 - 线Line

    目录 1. 点数组 2. 样式 2.1 宽度 2.2 颜色 2.3 末端形态 2.4 虚线 通过一组点绘制出相连的直线,通过lv_line_create创建相应的对象. 线只有LV_PART_MAIN ...

最新文章

  1. compass安装使用960 Grid System
  2. 受用一生的高效PyCharm使用技巧(二)
  3. linux vnc xstartup,vnc 远程桌面选择的配置 xstartup
  4. 安卓与ios都是linux,随便来说两句,安卓、IOS不是那么容易被取代的
  5. 循环结束后变回去 设置一个值_VBA掌握循环结构,包你效率提高500倍
  6. 一个平行四边形可以分成四个_将平行四边形分割成两个三角形还易变形么?(人教四下五单元三角形例2)...
  7. c++运行不出结果_fastjson 不出网利用总结
  8. cad2008加载 et拓展工具_生物信息工具 | 如何为网络图添加漂亮的图例?
  9. CLR via C# 3 读书笔记(4):第1章 CLR执行模型 — 1.4 执行程序集代码
  10. 如何将Linux还原为win10,技术编辑为你解说win10系统Linux Bash命令的还原步骤
  11. matlab详细手册,matlab详细手册
  12. python接口自动化代码_python接口自动化(十六)--参数关联接口后传(详解)
  13. Stemming and lemmatization
  14. 大数据笔记--Hadoop(第五篇)
  15. vue-学生的最爱抽签点名器
  16. Kaggle:入门赛Tatanic(泰坦尼克号)84.21%带你冲进前2%
  17. 计算机电子琴乐谱数字键,电子琴键盘与乐谱对照表.pdf
  18. python柱状图加百分比_【python】封装接口直接利用DataFrame绘制百分比柱状图
  19. matlab nlm,NLM.m · hr_yang/MatlabCode - Gitee.com
  20. C语言课程设计 管理系统

热门文章

  1. 吃糖果游戏(tyvj 1567)
  2. 红外光谱图解析知识大全(图文并茂)
  3. Python使用逻辑回归提示FutureWarning: Default solver will be changed to ‘lbfgs‘ in 0.22. Specify a solver to
  4. JVM:JVM常见参数配置
  5. 【BZOJ 1305】[CQOI2009]dance跳舞
  6. PHP获取唯一标识UUID
  7. linux车牌识别,基于嵌入式Linux的电子车牌识别系统设计与实现
  8. 学习java看什么论坛比较好
  9. linux中的文件夹压缩文件,linux将文件拷贝到目录下Linux下文件的压缩与打包详解...
  10. MySQL——创建存储过程和函数