【LVGL V8.x移植教程】

LVGL V8.x移植教程

官网下载LVGL源码,(可以通过github下载,也可以打包下载)甚至可以选择以前的版本进行下载
在这里插入图片描述
解压,得到下面的文件,我们暂时只用得上下面框住的文件
在这里插入图片描述
移植当中需要注意的是examples\porting文件夹下的文件,
在这里插入图片描述
还有就是src下面的源文件
在这里插入图片描述
准备好可以驱动显示器的MCU程序,这里以战舰板驱动3.5寸屏幕为例!!!
在这里插入图片描述
先在工程文件目录下创建文件夹“GUI”,在GUI文件夹下创建文件夹LVGL(文件夹的位置和名字不重要,在工程当中能够找到相关源程序即可)并将下载的源码文件夹下的所有文件复制到GUI文件夹下的LVGL文件夹下(我使用的是lvgl-8.0.3-dev)
在这里插入图片描述
把LVGL文件夹下的文件“lv_conf_template.h”剪切到上一层目录“GUI”下(注意是剪切),并将文件名改为lv_conf.h(你也可以不改,主要为了命名规范一点)
在这里插入图片描述
将GUI\LVGL\examples\porting文件夹下的文件命名进行更改,(你也可以不改,主要为了命名规范一点)如下图所示,暂时只用到显示部分,其他文件名暂时不更改。
在这里插入图片描述
打开工程,在工程当中创建三个文件夹,如下图所示:
在这里插入图片描述
然后将GUI文件夹目录下的文件“lv_conf.h”添加到“LVGL/USER”当中,将GUI\LVGL\examples\porting文件夹目录下的文件“lv_port_disp.c”添加到“LVGL/PORT”当中,将GUI\LVGL\src文件夹目录下的所有C文件添加到“LVGL/SRC”当中。
在这里插入图片描述
(GUI\LVGL\src\gpu文件夹下的文件暂时用不到,可以不用添加到工程当中,不过我还是添加到工程当中了)
添加头文件路径到工程当中,同时勾选上C99编译!!!
在这里插入图片描述
编译!!!查看错误
在这里插入图片描述
工程移植的差不多了,解析来就是移植LVGL的API了
首先打开文件“lv_port_disp.c”并使能,更改头文件名称(如果之前更改了GUI\LVGL\examples\porting文件夹目录下的文件名称的话),并添加显示屏的头文件,例如我的是:#include “nt35310_lcd.h”
在这里插入图片描述
然后打开对应的头文件“lv_port_disp.h”并使能,并添加函数”void lv_port_disp_init(void)“的声明
在这里插入图片描述
接下来我们需要更改函数“lv_port_disp.c”的内部实现方法!!!
首先我们需要对屏幕进行初始化,使用函数为:”disp_init()“,在函数内部实现对屏幕的初始化!!我在初始化完将屏幕刷新成浅蓝色了。

static void disp_init(void)
{
    /*You code here*/
	NT35310_LCD_Init();//LCD初始化
	NT35310_LCD_Clear(LIGHTBLUE);//填充浅蓝色  
}

然后是更改函数”void lv_port_disp_init(void)“,其在内部提供有三种设置缓冲区的方法,这里我们使用第一种,将其他方式先屏蔽掉,这里用到了头文件"nt35310_lcd.h"当中定义了表示屏幕分辨率的宏,我们需要使用到它,用来告诉LVGL屏幕的大小,更改内容如下

void lv_port_disp_init(void)
{
    //#defineNT35310_LCD_WIDTH320//LCD水平分辨率
    //#defineNT35310_LCD_HEIGHT480//LCD垂直分辨率
    /*-------------------------
     * 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 driver's `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 display's content here and writes it to your display
     *
     * 2. Create TWO buffer:
     *      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.
     *
     * 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 buffer's address.
     */
 
	/*-----------------------------------
     * 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 = NT35310_LCD_WIDTH;
    disp_drv.ver_res = NT35310_LCD_HEIGHT;

    /*Used to copy the buffer's content to the display*/
    disp_drv.flush_cb = disp_flush;

    /* Example for 1) */
    static lv_disp_draw_buf_t draw_buf_dsc_1;
    static lv_color_t buf_1[NT35310_LCD_WIDTH * 10];                          /*A buffer for 10 rows*/
    lv_disp_draw_buf_init(&draw_buf_dsc_1, buf_1, NULL, NT35310_LCD_WIDTH * 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_1[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_1, 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_1[MY_DISP_HOR_RES * MY_DISP_VER_RES];            /*An other 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 = 480;
//    disp_drv.ver_res = 320;

//    /*Used to copy the buffer's 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);
}

因为STM32F103没有GPU(DMA2D)功能,所以只能使用函数”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*/

    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)*/
			NT35310_LCD_DrawPoint(x, y, (color_p)++->full);
        }
    }

    /*IMPORTANT!!!
     *Inform the graphics library that you are ready with the flushing*/
    lv_disp_flush_ready(disp_drv);
}

到这里我们的显示API就移植的差不多了,解析来就是要开启LVGL!
开启LVGL需要调用以下函数,但是咱们暂时只用到了显示器,所以只需要调用前两个函数即可,后三个函数与下examples\porting文件夹下的文件一一对应。

lv_init();                  // lvgl初始化函数,在使用LVGL前必须调用
lv_port_disp_init();        // 显示器初始化
lv_port_indev_init();       // 输入设备初始化
lv_port_fs_init();          // 文件系统设备初始化

然后是使得LVGL进行心跳,需要调用以下函数

lv_tick_inc(LVGL_TICK);// tick 提供时钟,LVGL_TICK 一般为 5ms 即可
lv_timer_handler(); // 运行所有lvgl的timer

咱们暂时不使用RTOS,所以通过下面的方式进行初始化:

//添加头文件
#include "lv_port_disp.h"
#include <lvgl.h>

#define LVGL_TICK 5

int main(void)
{
    lv_init();
    lv_port_disp_init();        // 显示器初始化

    while(1)
    {
        // 先调用 lv_tick_inc 再调用 lv_timer_handler
        lv_tick_inc(LVGL_TICK);// tick 提供时钟,LVGL_TICK 一般为 5ms 即可
        lv_timer_handler(); // 运行所有lvgl的timer
        DelayMs(LVGL_TICK);
    }
}

最后一步,配置LVGL!!
打开配置文件"lv_conf.h"并使能,选择自己屏幕对应的颜色深度!!!
在这里插入图片描述
更改LVGL运行所使用的RAM大小:
在这里插入图片描述
开启监控设置
在这里插入图片描述
在主程序当中写入例子程序!!!
在这里插入图片描述
在这里插入图片描述
编译下载运行,结果如下:
在这里插入图片描述
更改堆栈空间的方法:
在这里插入图片描述
在这里插入图片描述

  • 6
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值