青岛市城阳区建设局网站,网站建设广州天河,长丰县建设局网站,棋牌推广如何精准引流LVGL移植说明 移植LVGL版本#xff1a;8.3.6 主控#xff1a;STM32F407ZGT6 github链接#xff1a;https://github.com/lvgl/lvgl.git 文章目录 LVGL移植说明STM32移植LVGL①需要的依赖文件②移植显示驱动文件③将文件加入工程当中④配置心跳④修改栈堆的空间⑤编译链接 STM…LVGL移植说明 移植LVGL版本8.3.6 主控STM32F407ZGT6 github链接https://github.com/lvgl/lvgl.git 文章目录 LVGL移植说明STM32移植LVGL①需要的依赖文件②移植显示驱动文件③将文件加入工程当中④配置心跳④修改栈堆的空间⑤编译链接 STM32移植LVGL
步骤说明
下载lvgl的数据包将lvgl的依赖文件加入工程当中修改LVGL的配置文件主要就是lv_port_disp_template文件和lv_conf文件的配置。配置心跳修改栈堆空间配置
注意事项
在官方的文档说明当中有这样的一个说明
基本上每个能够驱动显示器的现代控制器都适合运行 LVGL。最低要求是 16、32 或 64 位微控制器或处理器 推荐 16 MHz 时钟速度 闪存/ROM 64 kB 用于非常重要的组件建议 180 kB 内存 静态 RAM 使用~2 kB具体取决于使用的功能和对象类型堆栈 2kB建议 8 kB动态数据堆 2 KB如果使用多个对象建议 48 kB。LV_MEM_SIZE在lv_conf.h中设置。显示缓冲区 *“水平分辨率”*像素建议10 *“水平分辨率” *MCU 或外部显示控制器中的一个帧缓冲器 C99 或更新的编译器
①需要的依赖文件 还有examples里面的porting文件里面有三个.c文件和.h文件
其中lv_port_indev文件是对接触摸事件的
lv_port_disp对接显示事件
lv_port_fs对接文件管理事件
另外里面的三个文件的.c和.h都有一个开关需要用到哪个文件需得把相对应的开关打开。
除此之外还有一个lv_conf_template.h文件默认是把文件关闭的需要打开。除此之外 LVGL 的核心实现中都是使用 #include “lv_conf.h”所以 lv_conf_template.h 文件改名为 lv_conf.h 是必须要做的
②移植显示驱动文件
在这一个部分当中主要的就是lv_port_disp文件。要对屏幕的显示驱动进行对接。在这个文件当中主要配置两个函数。即disp_flush、lv_port_disp_init。主要对这两个文件进行配置。
首先要定义一下屏幕的分辨率大小
#define MY_DISP_HOR_RES 240
#define MY_DISP_VER_RES 320lv_port_disp_init函数
void lv_port_disp_init(void)
{/*-------------------------* Initialize your display* -----------------------*/disp_init();/*-----------------------------* Create a buffer for drawing*----------------------------*//*** LVGL requires a buffer where it internally draws the widgets.* Later this buffer will passed to your display drivers flush_cb to copy its content to your display.* The buffer has to be greater than 1 display row** There are 3 buffering configurations:* 1. Create ONE buffer:* LVGL will draw the displays content here and writes it to your display** 2. Create TWO buffer:* LVGL will draw the displays content to a buffer and writes it your display.* You should use DMA to write the buffers 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.** 3. Double buffering* Set 2 screens sized buffers and set disp_drv.full_refresh 1.* This way LVGL will always provide the whole rendered screen in flush_cb* and you only need to change the frame buffers address.*//* Example for 1) */static lv_disp_draw_buf_t draw_buf_dsc_1;static lv_color_t buf_1[MY_DISP_HOR_RES * MY_DISP_VER_RES/4]; /*A buffer for 10 rows*/lv_disp_draw_buf_init(draw_buf_dsc_1, buf_1, NULL, MY_DISP_HOR_RES * MY_DISP_VER_RES/4); /*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*//*-----------------------------------* Register the display in LVGL*----------------------------------*/static lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/lv_disp_drv_init(disp_drv); /*Basic initialization*//*Set up the functions to access to your display*//*Set the resolution of the display*/disp_drv.hor_res MY_DISP_HOR_RES;disp_drv.ver_res MY_DISP_VER_RES;/*Used to copy the buffers content to the display*/disp_drv.flush_cb disp_flush;/*Set a display buffer*/disp_drv.draw_buf draw_buf_dsc_1;/*Required for Example 3)*///disp_drv.full_refresh 1;/* Fill a memory array with a color if you have GPU.* Note that, in lv_conf.h you can enable GPUs that has built-in support in LVGL.* But if you have a different GPU you can use with this callback.*///disp_drv.gpu_fill_cb gpu_fill;/*Finally register the driver*/lv_disp_drv_register(disp_drv);
}在官方文档中有这么一个说明要有一个显示缓冲区帧缓冲区和至少 1/10 屏幕大小的缓冲区用于渲染。在这个函数里面官方给出了三种缓冲区模式分别是单缓冲区非全尺寸双缓冲区全尺寸双缓冲区。
初始化了屏幕的宽和高。即分辨率 disp_drv.hor_res MY_DISP_HOR_RES;disp_drv.ver_res MY_DISP_VER_RES; 还调用了一个回调函数对接底层和芯片平台相关的刷图接口。
disp_drv.flush_cb disp_flush;这个接口主要就是要对一个区域进行绘制并把颜色传入到里面。
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
// if(disp_flush_enabled) {
// /*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/// int32_t x;
// int32_t y;
// 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_p;
// }
// }
// }LCD_Color_Fill(area-x1,area-y1,area-x2,area-y2,(u16*)color_p);/*IMPORTANT!!!*Inform the graphics library that you are ready with the flushing*/lv_disp_flush_ready(disp_drv);
}这样就把基本的显示接口对接完成。
另外在配置lv_conf.h文件。
/*Color depth: 1 (1 byte per pixel), 8 (RGB332), 16 (RGB565), 32 (ARGB8888)*/
#define LV_COLOR_DEPTH 16/*Size of the memory available for lv_mem_alloc() in bytes ( 2kB)*/#define LV_MEM_SIZE (48U * 1024U) /*[bytes]*/
// 用于渲染和 LVGL 内部处理机制的 buffer 个数如果配置不够的话LVGL 会打印 ERROR 信息// 这个其实是一个 lv_mem_buf_arr_t[LV_MEM_BUF_MAX_NUM] 结构的数组个数
#define LV_MEM_BUF_MAX_NUM 16// 这个参数决定了多久处理一起屏幕刷新默认情况是 30ms
#define LV_DISP_DEF_REFR_PERIOD 30 /*[ms]*//*Input device read period in milliseconds*/
// 这个参数决定了多久处理一起input默认情况是 30ms
#define LV_INDEV_DEF_READ_PERIOD 30 /*[ms]*//*1: Show CPU usage and FPS count*/
#define LV_USE_PERF_MONITOR 1/*1: Show the used memory and the memory fragmentation* Requires LV_MEM_CUSTOM 0*/
#define LV_USE_MEM_MONITOR 0/*Default Dot Per Inch. Used to initialize default sizes such as widgets sized, style paddings.*(Not so important, you can adjust it to modify default sizes and spaces)*/
#define LV_DPI_DEF 130 /*[px/inch]*/LV_COLOR_DEPTH参数是设置颜色的深度。有三种模式可以供我们选择RGB332RGB565ARGB8888。三种根据自己屏幕进行选择即可。LV_MEM_SIZE是用于 LVGL 的动态申请/释放内存这里我们配置的 48KB 的全局数组给 LVGL 使用LV_MEM_BUF_MAX_NUM用于渲染和 LVGL 内部处理机制的 buffer 个数LV_DISP_DEF_REFR_PERIOD和LV_DISP_DEF_REFR_PERIOD用于处理屏幕的刷新周期在默认当中处于30ms刷新一次即满帧为33FPS。LV_USE_PERF_MONITOR用于打开或者关闭帧率的监控管理。LV_USE_MEM_MONITOR用于打开或者关闭内存的监控管理。
③将文件加入工程当中 将examples里面的porting文件加入工程、src里面的所有文件加入工程当中。
④配置心跳
LVGL 的任务都是基于时间的包含绘制响应触摸等等所以呢我们需要给它一个时间基准
LVGL 提供了一个 lv_tick_inc 的函数我们需要在系统中去周期性调用他告诉 LVGL 的时间基准可以用硬件 Timer也可以使用 SystemTick void TIM3_IRQHandler(void){/* USER CODE BEGIN TIM3_IRQn 0 *//* USER CODE END TIM3_IRQn 0 *//* USER CODE BEGIN TIM3_IRQn 1 *//* USER CODE END TIM3_IRQn 1 */if(LL_TIM_IsActiveFlag_UPDATE(TIM3) SET){LL_TIM_ClearFlag_UPDATE(TIM3);lv_tick_inc(1);// LL_GPIO_TogglePin(GPIOF, LL_GPIO_PIN_9);}}④修改栈堆的空间
在官方文档当中的最小配置文档说明根据其要求进行对栈堆的大小进行修改。 ⑤编译链接
在文档中说明使用C99的风格进行编码因此需要将KEIL配置中的C99选项进行勾选。
另外编译当中会有一些无关紧要的warning在 Options-C/C 的 Misc Controls 中加入以下命令即可。
--diag_suppress188 --diag_suppress111 --diag_suppress550