1 LVGL移植
本文使用的环境如下:
- STM32H743
- FreeRTOS
- st7789 lcd(320*240)
-
下载 LVGL源码,本文使用
Release v9.1.0
; -
将压缩包解压到工程目录,例如
stm32h7xx_cmake_project/components/lvgl-9.1.0
,如下所示: -
在工程目录下创建
LVGL
,其包含porting
、ui
和app
; -
将
lvgl-9.1.0
目录下的lv_conf_template.h
复制一份为lv_conf.h
, 并作以下修改:- 将
#if 0 /*Set it to "1" to enable content*/
改为#if 1 /*Set it to "1" to enable content*/
使能lv_conf.h
文件内容; - 定义
#define MY_DISP_HOR_RES 320
和#define MY_DISP_VER_RES 240
,指明显示屏的尺寸;
- 将
-
请根据主
CMakeLists.txt
,自行加入以下内容:
-
将
lvgl-9.1.0/examples/porting/lv_port_disp_template.c
和lvgl-9.1.0/examples/porting/lv_port_disp_template.h
复制到LVGL/porting
中,并重命名为lv_port_disp.c
和lv_port_disp.h
,该文件与显示屏以及lvgl初始化显示屏相关;- 将
#if 0
改为#if 1
,以使能文件内容; - 使用例子一方式显存,如下所示:
- 实现显示刷新到屏幕
- 将
-
在
app
文件夹中,创建lvgl_thread.c
和lvgl_thread.h
,如下:lvgl_thread.h
lvgl_thread.c
至此,移植工作已做完,直接构建工程,应该能编译通过。
2 LVGL性能测试
前面中,我们已经把LVGL的例子库添加到工程了,因此可以使用LVGL例子对系统进行性能测试。
- 打开
lv_conf.h
,修改以下宏定义:
lvgl_thread.c
中修改static void lvgl_thread_entry(void *arg)
:
- 编译运行可以发现,fps基本为0,这种情况下,与LVGL代码无太大关系了,与硬件平台相关,将在下一节分析原因并优化;
3 ST7789显示优化
st7789部分显示函数:
笔者在没有优化显示时,st7789 fps值很低,原因分析如下:
- st7789使用的是spi接口,每次只写一个点,时间开销都消耗在
LCD_Set_Windows
,此时软spi还是硬spi,速率差异不大; - stm32 spi速率过低;
- stm32 spi在无dma的情况对cpu资源开销大。
3.1 优化disp_flush
将原来每次只画一个点,改为填充一块区域,修改完后会发现fps值有所提高,大概fps为2-3,笔者spi速率92MHz。
分析LCD_Fill
,每画一个点需要执行LCD_Write_Data
两次,每次传输一个字节就要调用一次spi hal
库中的发送操作,时间开销都花在了函数调用上,是否减少函数调用次数能提高显示效果?
3.2 减少spi传输调用次数
将LCD_FILL
改为如下:
修改完后,发现fps大大提高了,大于15fps。虽然fps提高了,显示比较流畅,全屏刷时还是能看得出闪烁,但这种方式带来的是cpu开销过大,毕竟每次发送完都要等待发送完成。如果将spi
改为DMA
是否能降低cpu开销?
3.3 使用SPI DMA
此处贴出对HAL库SPI操作的二次封装,不对SPI DMA初始化讲解,毕竟STM32CubeMX能生成,本小节重点在于如何同步发送完成。下列使用了一个信号进行发送完成同步。
将spi改为dma方式传输之后,整个系统cpu占用有所大大降低,但是笔者之前spi使用了96MHz,此时显示屏颜色不对。说明spi时序已经超限了,此时需要降低SPI传输速率,笔者将96MHz降至48MHz,显示就正常了。虽然SPI传输速率降低,但是fps值未受影响。