文章标题

  • 准备
    • STM32F429I-DISC1 开发版
    • CUBEMX 工具
  • 移植
    • CUBEMX生成基础代码
      • FREERTOS
      • 时钟树
      • 生成
    • LVGL库移植
    • LVGL 驱动 触摸屏
      • 显示
      • 触摸
    • 导入keil并编译
  • 烧录
  • 附件

本文只针对当时的LVGL v7,LVGL迭代过程中变化较大,部分接口有可能做调整。本文仅供参考

准备

之前的f103的开发版移植了LVGL,分辨率240*320屏幕,如果只有Gauge这种界面局部刷新的控件效果还算差强人意,但只要全屏刷新的话帧数只有十几帧,观感较差。使用场景感觉挺受限。
感觉103这种性能还是不太能玩转GUI,之前看touchgfx也挺卡的。
前几天搞到一块f429 discovery开发版,就再次尝试移植了lvgl,效果不错。

STM32F429I-DISC1 开发版

开发版参数
芯片参数
在这里需要注意的参数
使用的是•STM32F429ZIT6
180 MHz
LTDC 驱动( LCD-TFT controller) :屏的驱动,只需要指定显存地址,ltdc会自动dma将显存数据传到tft,比并口快,不过个人没测试过速度差异。
DMA2D:简单来说就是,专门为刷显存的设计的特殊的DMA,带有的图层混合,纯色填充,像素格式转换,显示窗口等功能,比较好用。

CUBEMX 工具

下载地址
方便快速配置外设及一些中间件,可直接生成代码。

移植

CUBEMX生成基础代码

需要主要包括以下几个。注意生成的外设配置代码只包含MCU自身的初始化,部分如SDRAM,tft之类的需要另外初始化外设。不过我这里图省事直接用bsp包初始化了显示ic,ltdc,触摸ic,sdram等。就不用这个工具配置了

FREERTOS

例程放一个刷UI的高优先级进程,专门刷UI。任务栈设置成2k byte,其他默认。

时钟树

180M,如下

生成

这里我用的是keil,可按自己需求生成不同的ide项目。

LVGL库移植

在生成的项目里新建 你的工程路径\Middlewares\Third_Party\Lvgl文件夹
将下载的LVGL源码
LVGL源码及example放到该文件夹中
将lvgl/lv_conf_template.h配置文件模板拷贝到LVGL源码上一级目录,改名lv_conf.h,将文件里#if 0 改成#if 1,并按屏幕类型修改分辨率及色深,设置LVGL内存堆大小,并使能使能custom tick ,让lvgl使用freertos的心跳tick,其余默认。

#define LV_HOR_RES_MAX          (240)
#define LV_VER_RES_MAX          (320)
#define LV_COLOR_DEPTH     16
#  define LV_MEM_SIZE    (32U * 1024U)
#define LV_TICK_CUSTOM     1
#if LV_TICK_CUSTOM == 1
#define LV_TICK_CUSTOM_INCLUDE  "FreeRTOS.h"       /*Header for the sys time function*/
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (xTaskGetTickCount())     /*Expression evaluating to current systime in ms*/
#endif   /*LV_TICK_CUSTOM*/

调用lv_init()以初始化库,并在ui进程中周期性调用lv_task_handler()即可LVGL库的使用

LVGL 驱动 触摸屏


LVGL和硬件层的交互很简单,只是给driver层提供需要刷新的显存buffer及显示窗口而已,
将lvgl\examples\porting里的lv_port_disp_template与lv_port_indev_template c文件和h文件拷贝出来,一个是LVGL显示驱动模板,一个是LVGL触摸驱动模板
里面需要改动的东西,只有两个对应的回调函数,

显示

LVGL显存稍微改大点,默认是屏幕10行像素点刷一轮,我们改成40行,差不多就能保证默认满帧运行了

         static lv_disp_buf_t draw_buf_dsc_1;static lv_color_t draw_buf_1[LV_HOR_RES_MAX *40] ;  /*A buffer for 10 rows*/lv_disp_buf_init(&draw_buf_dsc_1, draw_buf_1, NULL, LV_HOR_RES_MAX *40);   /*Initialize the display buffer*/

显示回调函数修改,dma2d刷屏

extern DMA2D_HandleTypeDef hdma2d;
extern LTDC_HandleTypeDef hltdc;
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*/int16_t w = (area->x2 - area->x1 + 1);int16_t h = (area->y2 - area->y1 + 1);uint32_t size = w * h;disp_drv_p = disp_drv;hdma2d.Init.Mode         = DMA2D_M2M;hdma2d.Init.ColorMode    = DMA2D_OUTPUT_RGB565;hdma2d.Init.OutputOffset = (LV_HOR_RES_MAX-w);     hdma2d.LayerCfg[1].AlphaMode = DMA2D_NO_MODIF_ALPHA;hdma2d.LayerCfg[1].InputAlpha = 0xFF;hdma2d.LayerCfg[1].InputColorMode = DMA2D_INPUT_RGB565 ;hdma2d.LayerCfg[1].InputOffset = 0;hdma2d.Instance          = DMA2D; /*##-4- DMA2D Initialization ###############################################*/if(HAL_DMA2D_Init(&hdma2d) != HAL_OK) {Error_Handler(); }if(HAL_DMA2D_ConfigLayer(&hdma2d, 1) != HAL_OK) {/* Initialization Error */Error_Handler(); }if(HAL_DMA2D_Start(&hdma2d, (uint32_t)color_p, (uint32_t) (hltdc.LayerCfg[0].FBStartAdress) + 2*(LV_HOR_RES_MAX *area->y1 + area->x1), w, h) != HAL_OK){/* Initialization Error */Error_Handler(); }HAL_DMA2D_PollForTransfer(&hdma2d,100);lv_disp_flush_ready(disp_drv);
}

触摸

触屏驱动,更改的如下图,主要是获取xy坐标及触摸状态,并提供给lvgl

 static TS_StateTypeDef  TS_State;
static bool touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
{static lv_coord_t last_x = 0;static lv_coord_t last_y = 0;BSP_TS_GetState(&TS_State); /*Save the pressed coordinates and the state*/if(touchpad_is_pressed()) {touchpad_get_xy(&last_x, &last_y);data->state = LV_INDEV_STATE_PR;} else {data->state = LV_INDEV_STATE_REL;}/*Set the last pressed coordinates*/data->point.x = last_x;data->point.y = last_y;/*Return `false` because we are not buffering and no more data to read*/return false;
}
/*Return true is the touchpad is pressed*/
static bool touchpad_is_pressed(void)
{/*Your code comes here*/return TS_State.TouchDetected;
}/*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*/*x = Calibration_GetX(TS_State.X);*y = Calibration_GetX(TS_State.Y);
}

将void lv_port_disp_init(void)及void lv_port_indev_init(void)声明加入到对应头文件中,lvgl初始化块同时调用void lv_port_indev_init(void)及void lv_port_indev_init(void)即可。

void StartUITask(void *argument)
{/* USER CODE BEGIN 5 */lv_init();lv_port_disp_init();lv_port_indev_init();lv_demo_widgets();/* Infinite loop */for(;;){lv_task_handler();osDelay(1);}/* USER CODE END 5 */
}

导入keil并编译


图上的路径include进来,keil项目添加对应group,将lvgl源代码、bsp驱动,lvgl_example测试用例添加进来
由于用了bsp包初始化了显示ic,spi和iic,所以stm32f4xx_hal_conf.h需要开启对应的编译开关。


接下来还有一些头文件没有包含进来
对应的头文件include处理一下可以烧录了。

#include "lvgl.h"
#include "lv_examples.h"
#include "lv_port_disp.h"
#include "lv_port_indev.h"
#include "stm32f429i_discovery.h"
#include "stm32f429i_discovery_lcd.h"
#include "stm32f429i_discovery_ts.h"

烧录

效果如下,lvgl默认LV_DISP_DEF_REFR_PERIOD 30ms刷新一次,满帧33帧,基本全程满帧运行。
至于优化提高刷新率的方法,后面再做详细介绍。

附件

例程

f429 discovery开发版 LVGL移植(带操作系统)相关推荐

  1. 天嵌开发版 imx6 移植qt

    1.环境说明 QT 移植 - 系统: ubuntu 14.04 x64 - 编译器: arm-none-linux-gnueabi-gcc 4.8.3 - QT 5.5.1 2.下载源码 - 下载交叉 ...

  2. 海思开发板hi3559移植带opengl的qt并成功运行血泪史

    几个必不可少的流程:环境linux系统 1,安装海思交叉编译工具.2,编译qt库,配置qt编译构件,拷贝qt库到板子3,编译海思sdk(为编译gpu做准备).4,编译海思gpu kernel.5,修改 ...

  3. 小米9开发版自带root吗_小米手机MIUI9开发版开启ROOT权限方法,这些经验不可多得...

    小米MIUI9系统如何获取ROOT权限呢?相比其它品牌手机系统而言,MIUI9开发版系统自带ROOT权限管理工具,如果想获取MIUI系统ROOT权限,只需要根据下面的方法进行操作即可. 操作方法 01 ...

  4. LwIP应用开发笔记之十:LwIP带操作系统基本移植

    现在,TCP/IP协议的应用无处不在.随着物联网的火爆,嵌入式领域使用TCP/IP协议进行通讯也越来越广泛.在我们的相关产品中,也都有应用,所以我们结合应用实际对相关应用作相应的总结. 1.技术准备 ...

  5. 开发板移植RTOS操作系统,RTOS操作系统适配开发板整理大全

    文章目录 一.单片机/嵌入式有无操作系统的区别 二.操作系统时的分层架构图 三.移植FreeRTOS到小熊派开发板(STM32L431RC) 1. 硬件准备 2. 下载FreeRTOS源码 2.1. ...

  6. 基于MDK开发的TencentOS-Tiny软件包,快速移植物联网操作系统到Keil中!

    基于MDK开发的TencentOS-Tiny Software Pack 2021腾讯犀牛鸟开源人才培养计划 2021/9/24 项目导师:TencentOS tiny核心架构师 汪礼超 项目学员:东 ...

  7. 深度剖析E680G开发四.移植OPIE操作系统(中)-交叉编译Qte

    一.前言         虽然是E680系列的开发环境,其实就是嵌入式方面的知识.在上文详细了解了 E680g系统结构,图形化发展历程,到这篇文章就要实实在在去做了.     最早移植成功的是一位外国 ...

  8. 深度剖析E680G开发三.移植OPIE操作系统(上)

    深度剖析E680G开发三.移植OPIE操作系统(上) 草木瓜 20060918 一.前言         凡事我图写的文章,往往比较内容纵深,范围却很窄,注重实际操作.原因 很简单,水平有限,还达不到 ...

  9. 深度剖析E680G开发五.移植OPIE操作系统(下)-编译和运行OPIE

    深度剖析E680G开发五.移植OPIE操作系统(下)-编译和运行OPIE 草木瓜 20060930 一.前言               这是最后的内容,然而却有很大的遗憾,如果运行OPIE,但E68 ...

最新文章

  1. oracle 优化逻辑读过高,详述逻辑读与arraysize的关系
  2. ios 支付宝支付 回调数据_iOS逆向支付宝
  3. 苹果支付招聘业务开发经理 需有加密货币支付工作经验
  4. 搜狗浏览器收藏夹在哪_chrome谷歌浏览器收藏夹在哪_chrome收藏夹在电脑什么位置...
  5. 操作系统(1) 发展历史
  6. 万亿级新基建战场,阿里云的安全“防线”
  7. setTimeout()方法和setInterval()方法
  8. linux最小化连接开放wifi,CentOS最小化安装后启用无线连接网络
  9. 博客V7之后,喜庆排名进入2000之内
  10. C#.NET身份证验证算法
  11. 【社会相关】:大神写的考研政治复习攻略
  12. Windows 下部署 Seafile 服务器
  13. 微信大数据挑战赛决赛方案:微信视频号推荐算法
  14. Android 高级面试
  15. php 301目录对应,PHP 301转向实现代码
  16. VVC帧内预测(六)MIP
  17. 学计算机编程难吗,计算机编程入门 计算机编程难学吗
  18. Sheldon的小本本 (10 分)
  19. 记录:macbook 下剪切快捷键
  20. 提笔忘字:时代进步还是退步?

热门文章

  1. FinTech头条丨祝贺国家电投全球司库管理系统成功上线!
  2. JeecgBoot 2.0.2 版本发布,基于SpringBoot快速开发平台
  3. ettercap局域网劫持
  4. 为什么你的工作总是没能做好呢?
  5. android开发笔记之网络编程—简易新闻客户端
  6. 果蝇优化算法(FOA)原理
  7. 华为云找到 “成功”路径
  8. BIM技术到底是什么技术?学会了可以从事什么工作?
  9. 4个方法:Excel筛选重复项
  10. 借鉴:软考高项备考考试心得,来自一名学员的总结,非常全