LVGL8.2移植学习

**

LVGL8.2移植学习

链接: LVGL官网.
**

LVGL8.2文件组成

lvgl8.2各个文件夹的作用

LVGL8.2移植所需的文件

文件描述路径
demos官方的示例(可要可不要)lvgl-release-v8.2 / demos
porting显示输入输出接口(API)lvgl-release-v8.2 / examples / porting
srclvgl的源文件lvgl-release-v8.2 / src
lv_conf_template.hlvgl配置文件lvgl-release-v8.2 / lv_conf_template.h
lvgl.h头文件lvgl-release-v8.2 / lvgl.h

Keil工程中移植源码

  • 将src内的文件添加入工程中,在魔术棒中记得添加src中文件夹的头文件路径,不要忘记lv_conf_template.h和lvgl.h路径的添加,文件列表如下图所示:

在这里插入图片描述
注:由于暂时没有使用DMA2D故以上文件夹目录没有LVGL / src / gpu。

文件夹需添加的文件
example / portingexamples / porting文件夹下的lv_port_disp_template.c;带触摸的需添加lv_port_indev_template.c文件
src / corelvgl-release-v8.2 / src / core文件夹下所有的.c文件
src / drawlvgl-release-v8.2 / src / draw添加文件夹下除nxp_pxp、nxp_vglite、sdl和stm32_dmazd文件夹之外的全部.c文件
src / extralvgl-release-v8.2 / src / extra添加该文件夹下所有.c文件
src / fontlvgl-release-v8.2 / src / font添加该文件夹下所有.c文件
src / hallvgl-release-v8.2 / src / hal添加该文件夹下所有.c文件
src / misclvgl-release-v8.2 / src / misc添加该文件夹下所有.c文件
src / widgetslvgl-release-v8.2 / src / 添加该文件夹下所有.c文件
src / gpulvgl-release-v8.2 / src / draw添加该文件夹下draw / sdl和draw / stm32_dmazd中所有的.c文件

修改移植的lvgl文件

注:修改之前应当将LCD、IPS等显示屏幕对应的驱动文件加入到Keil工程中。

1. 把lv_conf_template.h改为lv_conf.h,lv_port_disp_template.h改为lv_port_disp.h,分别修改两个文件中的条件编译指令:
	#if 1 /*Set it to "1" to enable content*/
	/*Copy this file as "lv_port_disp.h" and set this value to "1" to enable content*/
	#if 1
以下内容在lv_port_disp.c文件中编辑
2. 在disp_init(void)函数中调用屏幕初始化函数,如下:
	/*Initialize your display and the required peripherals.*/
	static void disp_init(void)
	{
	    /*You code here*/
		LCD_Init();
	}
3. 配置图像数据缓冲模式
  • lv_port_disp_init(void)函数中,官方提供有以下缓冲模式可选择;
	    /* Example for 1) */
    static lv_disp_draw_buf_t draw_buf_dsc_1;
    static lv_color_t buf_1[MY_DISP_HOR_RES * 10];                          /*A buffer for 10 rows*/
    lv_disp_draw_buf_init(&draw_buf_dsc_1, buf_1, NULL, MY_DISP_HOR_RES * 10);   /*Initialize the display buffer*/

    /* Example for 2) */
    static lv_disp_draw_buf_t draw_buf_dsc_2;
    static lv_color_t buf_2_1[MY_DISP_HOR_RES * 10];                        /*A buffer for 10 rows*/
    static lv_color_t buf_2_2[MY_DISP_HOR_RES * 10];                        /*An other buffer for 10 rows*/
    lv_disp_draw_buf_init(&draw_buf_dsc_2, buf_2_1, buf_2_2, MY_DISP_HOR_RES * 10);   /*Initialize the display buffer*/

    /* Example for 3) also set disp_drv.full_refresh = 1 below*/
    static lv_disp_draw_buf_t draw_buf_dsc_3;
    static lv_color_t buf_3_1[MY_DISP_HOR_RES * MY_DISP_VER_RES];            /*A screen sized buffer*/
    static lv_color_t buf_3_2[MY_DISP_HOR_RES * MY_DISP_VER_RES];            /*Another screen sized buffer*/
    lv_disp_draw_buf_init(&draw_buf_dsc_3, buf_3_1, buf_3_2, MY_DISP_VER_RES * LV_VER_RES_MAX);   /*Initialize the display buffer*/

注:在LVGL8.2中单缓冲和双缓冲效果区分不明显(可能官方没有优化好)

缓冲模式内存要求
1- 单缓存10行像素点*颜色深度对应字节数(RGB565-2个字节)内存允许可开辟大一点空间提高显示效果。
2- 双缓冲210行像素点颜色深度对应字节数(RGB565-2个字节)
3-全屏双缓冲相当于建立两个和屏幕分辨率相当的缓冲区,对SRAM要求比较高
4. 在lv_port_disp_init()函数中找到如下代码,设置自己的屏幕尺寸(注意自己的屏幕初始化是横屏还是竖屏)
 	   /*Set the resolution of the display*/
       disp_drv.hor_res = 320;
       disp_drv.ver_res = 480;
5. 在disp_flush()函数中配置画点函数
   	 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*/
   	#if 1
   	    int32_t x;
   	    int32_t y;
   		  uint16_t color=0xFF08;
   		  uint16_t *color_px=(uint16_t *)color_p;
   		  uint16_t height,width;   
   		  height=area->y2 - area->y1;
   	    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)*/
   					  	//color = color_px[(y-area->y1)*height+(x-area->x1)];
   						    POINT_COLOR = color_p->full;
   						    LCD_DrawPoint(x,y);
   	            color_p++;
   	        }
   	    }
   	#else
   			//LCD_Color_Fill(area->x1,area->y1,area->x2,area->y2,(uint16_t*)color_p);
   		   LCD_Color_Fill(area->x1, area->y1, area->x2, area->y2, (uint16_t*)color_p);
   	 
   	#endif
   		/*IMPORTANT!!!
   	     *Inform the graphics library that you are ready with the flushing*/
   	    lv_disp_flush_ready(disp_drv);
   	}

LVGL输入配置(这里以EC11编码器为例)

注:修改之前应当将EC11编码器(或其他输入设备)对应的驱动文件加入到Keil工程中。

1.把lv_port_indev_template.h改为lv_port_indev.h,lv_port_indev_template.c改为lv_port_indev.c分别修改两个文件中的条件编译指令:

在这里插入图片描述
在这里插入图片描述

2.裁剪lv_port_indev.c内容,保留所需宏定义和函数定义

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

3.编辑编码器初始化函数、回调函数

在这里插入图片描述

在这里插入图片描述

4.在主程序调用LVGL输入设备初始化函数

在这里插入图片描述

为LVGL提供时基

添加定时器时基

1. 添加定时器驱动.c文件,可以通过STM32CubeMX直接配置生成。
2. 在定时器的.c文件中#include "lvgl.h"
3. 在定时器中断函数或回调函数中调用lv_tick_inc(x)
	//在该回调函数中添加lv_tick_inc(1)-----
	/***************推荐****************/
	void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
	{
		//if(htim->Instance == BTIM_)
			lv_tick_inc(1);
	}
	/***************不推荐****************/
	void BTIM_TIMX_INT_IRQHandler()
	{
	  HAL_TIM_IRQHandler(&htim3);
	}
  1. 初始化定时器并保证中断时间间隔==xms

测试程序的编写

1. main.c中包含以下头文件:
	#include "lvgl.h"
	#include "lv_port_disp.h"
2. mian()函数中初始化定时器、LVGL库、输入输出设备
	MX_TIM3_Init();
	HAL_TIM_Base_Start_IT(&htim3);
	lv_init();
	lv_port_disp_init();
3. while(1)主循环中每隔一段时间调用以下函数,调用
	HAL_Delay(5);
	lv_task_handler();
4. 内存管理(在lvgl_conf.h中) 默认是设置了48k的内存

注:如果系统内存不够会报错,可适当减少内存分配

		/*1: use custom malloc/free, 0: use the built-in `lv_mem_alloc()` and `lv_mem_free()`*/
	#define LV_MEM_CUSTOM 0
	#if LV_MEM_CUSTOM == 0
	    /*Size of the memory available for `lv_mem_alloc()` in bytes (>= 2kB)*/
	    #define LV_MEM_SIZE (48U * 1024U)          /*[bytes]*/
	
	    /*Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too.*/
	    #define LV_MEM_ADR 0     /*0: unused*/
	    /*Instead of an address give a memory allocator that will be called to get a memory pool for LVGL. E.g. my_malloc*/
	    #if LV_MEM_ADR == 0
	        //#define LV_MEM_POOL_INCLUDE your_alloc_library  /* Uncomment if using an external allocator*/
	        //#define LV_MEM_POOL_ALLOC   your_alloc          /* Uncomment if using an external allocator*/
	    #endif
	#else       /*LV_MEM_CUSTOM*/
	    #define LV_MEM_CUSTOM_INCLUDE <stdlib.h>   /*Header for the dynamic memory function*/
	    #define LV_MEM_CUSTOM_ALLOC   malloc
	    #define LV_MEM_CUSTOM_FREE    free
	    #define LV_MEM_CUSTOM_REALLOC realloc
	#endif     /*LV_MEM_CUSTOM*/

压力测试例程移植

  1. 将lvgl-release-v8.2 / demos 复制到工程下
  2. 添加lv_demo_stress.c和相关.h的路径
  3. lv_conf.h文件中,最下面找到以下宏定义,置1。
    #define LV_USE_DEMO_STRESS      0  
    
  4. main.c中包含
    #include "lv_demo_stress.h"
    
  5. 初始化官方demo
    	lv_demo_stress();
    

其他

lv_conf.h中设置显示FPS和CPU占用
	/*1: Show CPU usage and FPS count*/
	#define LV_USE_PERF_MONITOR 1

在FreeRTOS上运行LVGL8.2需要修改的点

  1. 使用FreeRTOS获取时间的函数xTaskGetTickCount()为LVGL提供时基;(可删除定时器提供时基代码)(但未测试成功,调试出现FreeRTOS和LVGL的任务调度出现冲突,还没找到问题原因)
    在这里插入图片描述
  2. 通过FreeRTOS的Tick滴答钩子函数实现LVGL的心跳获取,空闲任务钩子函数实现LVGL的任务管理(测试成功);该方法参考freeRTOS&LVGL|在使用freertos时如何为lvgl配置心跳和任务管理器实现。
  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在将lvgl 8.2移植STM32平台上的过程中,首先需要准备一个完整的STM32工程,包括定时器中断和LCD屏幕驱动。同时需要准备lvgl的源码文件,最新版本为8.3。然后按照以下步骤进行移植: 1. 在STM32工程目录下创建一个名为lvgl的文件夹,用于存放lvgl的所有文件。 2. 将lvgl源码中的src和examples/porting这两个文件夹,以及lv_conf_template.h和lvgl.h复制到刚刚创建的lvgl文件夹中。 3. 删除porting文件夹下所有文件的"template"后缀,并将lv_conf_template.h也去掉后缀。 4. 将src和porting文件夹下的所有文件添加到STM32工程目录中。 5. 在工程中添加三个路径,并将lv_conf.g、lv_port_disp.c和lv_port_disp.h中的if 0改为if 1。然后任选一个绘制函数,注释掉其他两个,同时修改draw_buf那行代码为你选择的绘制函数。 6. 在disp_init函数中添加屏幕初始化函数,在disp_flush函数中添加绘制函数。需要注意的是,color_p是一个指针,存储了矩形区域内每个点的像素值,而不是整个区域显示一个颜色。 7. 在定时器中断中添加相应的函数。 8. 在主函数中初始化lvgl、显示设备,并调用timer_handler函数。 9. 在lv_conf.h中开启相应的宏定义。 10. 运行程序,如果没有错误,就可以在屏幕下方看到内存占用率和帧率,这样就可以确保lvgl是否可以正常显示了。 这样就完成了将lvgl 8.2移植STM32平台上的过程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值