LVGL移植-基于STM32H750VB

lvgl移植

 

代码资料请到www.wujique.com上找

例程放在百度云.

2020.06.21

本文档建议用Typora浏览。

LVGL是啥?

lvgl是一个GUI,或者,可以认为是一个应用层的输入框架。

github

https://github.com/lvgl/lvgl

demo

https://github.com/lvgl/lv_examples

更新比较频繁,现在已经是7.0版本。

移植

网络很多人移植了,但是都只是说,额,我移植了lvgl。

下面这个,说的还算详细,不过,LVGL现在7.0了,LVGL的代码文件夹组织方式已经改动较大。

以前大家就经常吐槽它逻辑不好。

https://blog.csdn.net/qq_42992084/article/details/105882751

之前

本次移植到STM32H750VB,没有外挂RAM。在移植之前,需要说明一些问题。

显存

显存就是RAM。

经常有人问,H750VBT能支持多大的LCD?

  1. 如果是MCU接口的LCD,本来显存就是放在LCD控制器上,所以,理论上说,多大的LCD都可以点亮。但是越大的屏,刷新时间也长。
  2. RGB接口屏,这种屏通常是没有显存的。比如STM32的LTDC控制器,控制一个RGB接口的屏,就需要在芯片内部开辟显存。
  3. 一个16bit的RGB屏,1个点需要2个字节,480x272像素的LCD,就需要480x272x2字节,也就是255K。
  4. 如果RAM充足,通常做两层显存,一层用于刷新显示,一层用于修改,修改好后,切换为刷新显存,原来显示的显存改为用于修改。
  5. STM32H750VB 号称 内置有1M RAM,那是不是就可以开辟两层显存呢?

H750的内存

是否可以在H750上开辟两层480*272像素的显存?理论可以,目前没搞定

为什么?我们先看看H750的架构。

文档:dm00314099-stm32h742-stm32h743753-and-stm32h750-value-line-advanced-armbased-32bit-mcus-stmicroelectronics.pdf

看上面这个图,1M的内存,分为多块,功能都有差异。跟LTDC连在一起的,只有512K,AXI SRAM。

在STM32CUBEIDE的编译结果中其实也可以看到:

也就是说,LTDC,可以用作显存的RAM,至多也就512K,看起来能开辟两层显存。

但是,CPU直接连接的也只有AXI,堆栈这种东西,估计也是放在这里,除去510K显存,剩2K,我觉得可能不够的。

待研究,待研究。

lvgl内存

分两部分,显存和内存消耗。

内存消耗,不算显存,内存要几十K。

显存呢?由我们定。

lv_port_disp_.c 文件的lv_port_disp_init函数中,有这样一段话:

/* LVGL requires a buffer where it draws the objects. The buffer's has to be greater than 1 display row *

  • There are three buffering configurations:

    1. Create ONE buffer with some rows:
  • LVGL will draw the display's content here and writes it to your display

  •  

    1. Create TWO buffer with some rows:
  • LVGL will draw the display's content to a buffer and writes it your display.

  • You should use DMA to write the buffer's content to the display.

  • It will enable LVGL to draw the next part of the screen to the other buffer while

  • the data is being sent form the first buffer. It makes rendering and flushing parallel.

  •  

    1. Create TWO screen-sized buffer:
  • Similar to 2) but the buffer have to be screen sized. When LVGL is ready it will give the

  • whole frame to display. This way you only need to change the frame buffer's address instead of

  • copying the pixels.

  • */

翻译为中文就是:

LVGL需要显存,有3种方法:

  1. 单个局部显存。
  2. 双局部显存
  3. 双全显存。

双全显存就是前面说的双显存。

局部显存的数据逻辑就是,LCD驱动要有一个全显存, LVGL只要局部显存,将局部显存的内容填到LCD显存完成显示。

开工

现在正是开始测试LVGL的一个DEMO。基于STM32H750VB,无外挂RAM,480*272像素的RGB屏,电容触摸。

程序基于STM32H750 RGB屏的DEMO。

  • 下载

    https://github.com/lvgl/lvgl

    https://github.com/lvgl/lv_examples

    下载后解压,文件夹改名为lvgl和lv_examples,丢到H750_cube_demo_LVGL\User\目录下。

  • 清理

    examples里面很多demo,我们只用一个。其他的删除。

    demo在src目录,保留ex的3个文件夹和widgets文件夹。

  • 配置

    拷贝lv_examples目录的lv_ex_conf_templ.h到lv_examples外,改名为lv_ex_conf.h。

    打开这个头文件,打开开头的条件编译。

    配置demo widget

    拷贝lvgl目录的lv_conf_template.h文件到lvgl外,改名为lv_conf.h。

    打开这个头文件,打开文件前面的条件编译。

    配置屏幕信息

  • PORT

    PORT就是移植,就是实现接口。

    在目录H750_cube_demo_LVGL\User\lvgl\porting\有例子,复制一份,文件名去掉_template,再修改。

    总共有3个接口需要实现:LCD显示,触摸输入,文件系统。

    首先,打开这几个文件的条件编译。

    第二,LCD初始化函数lv_port_disp_init,选择显存模式,现在,我们先用第二种。

    第三,实现disp_flush函数,不好意思,在这个demo中,只有这是我添加的。直接将显示内容复制到显存。

     

     

  • 应用

    这是main函数的一部分,在这之前,LCD已经初始化好。

  • 触摸输入

    本次移植基于电容屏的LCD。

    程序已经完成GT9147驱动开发,能读到电容屏的触摸点值。

    对接LVGL的文件在lv_port_indev.c文件。触摸屏相关的函数有两个:touchpad_is_pressedtouchpad_get_xy

    touchpad_is_pressed函数用于判断当前是否触摸。

    touchpad_get_xy获取触摸点的xy坐标。

    功能理解起来不难,但是有个隐藏的技术点要提前了解:生产者和消费者的速度不匹配。

    生产者,就是电容屏驱动,就是扫描到触摸点的函数。

    消费者就是LVGL的touchpad_read函数。

    不匹配的表现是:

    1. 驱动扫描得到几个点了,LVGL不读取。
    2. LVGL连续读几次,却由于驱动没有扫描,所以读不到点。

    匹配生产者个消费者的方法,可以用缓冲。缓冲的原理就是削峰填谷。

    扫描到点后,先放到缓冲。LVGL读点也是从缓冲读取。

    使用缓冲之后,对于触摸屏来说,就有一个问题需要认识:

    读不到点,并不代表当前没有触摸。

    具体实现请看代码。

  • 效果

 

后记

在 stm32h750vb上移植了,全屏刷新时,不是很平滑。

是触屏问题还是刷屏问题?待优化。