打印
[学习笔记]

AC781X开发板移植littlevGL(LVGL)

[复制链接]
12518|58
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 linguanghua 于 2021-9-1 16:13 编辑

上次移植过单色屏的GUI到AC781X开发板,现在找个彩屏,移植littlevGL(选择叫LVGL)。这个GUI版本更新很快,我最初使用是2019年,那时候国内很少人使用,现在已经更新到8.0版本了,已经很流行了,而原来的API已经面目全非。V7中的原来自带的task任务系统变成V8中的timer,不过本质上是一样的,定时调用。

0.开始移植,准备一个可正常使用的工程,包含LCD驱动。工程目录新建文件夹“LVGL”。

1.下载LVGL代码。目前最新V8.1了。
源码:https://github.com/lvgl/lvgl
官网:https://lvgl.io/
2.文档lvgl-master解压,复制文件夹“src”,文件lvgl.h和lv_conf_template.h 到文件夹“LVGL”,复制 examples下porting文件夹到文件夹“LVGL”。
3.文件夹“LVGL”下,将lv_conf_template.h改名为lv_conf.h,此文件内部,将开头的 #if 0 改为 #if 1,#define LV_COLOR_DEPTH     16这里修改为LCD位深。
此文件内有许多宏定义,可开关特定的功能、性能。
4.将lv_port_disp_template.c改名lv_port_disp.c,对应.H文件名也要修改。
lv_port_disp.c修改如下:(不知道为什么显示不了)
/**
* [url=home.php?mod=space&uid=288409]@file[/url] lv_port_disp_templ.c
*
*/

/*Copy this file as "lv_port_disp.c" and set this value to "1" to enable content*/
#if 1

/*********************
*      INCLUDES
*********************/
#include "lv_port_disp.h"
#include "../../lvgl.h"
#include "lcd.h"

/*********************
*      DEFINES
*********************/

/**********************
*      TYPEDEFS
**********************/

/**********************
*  STATIC PROTOTYPES
**********************/
static void disp_init(void);

static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
//static void gpu_fill(lv_disp_drv_t * disp_drv, lv_color_t * dest_buf, lv_coord_t dest_width,
//        const lv_area_t * fill_area, lv_color_t color);

/**********************
*  STATIC VARIABLES
**********************/

/**********************
*      MACROS
**********************/
/* Maximal horizontal and vertical resolution to support by the library.*/
#define MY_DISP_HOR_RES          (160)  //320
#define MY_DISP_VER_RES          (128)  //480
/**********************
*   GLOBAL FUNCTIONS
**********************/

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 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.
     */

    /* 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*/


    /*-----------------------------------
     * 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 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);
}

/**********************
*   STATIC FUNCTIONS
**********************/

/*Initialize your display and the required peripherals.*/
static void disp_init(void)
{
    /*You code here*/
}

/*Flush the content of the internal buffer the specific area on the display
*You can use DMA or any hardware acceleration to do this operation in the background but
*'lv_disp_flush_ready()' has to be called when finished.*/
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*/

    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);
}

/*OPTIONAL: GPU INTERFACE*/

/*If your MCU has hardware accelerator (GPU) then you can use it to fill a memory with a color*/
//static void gpu_fill(lv_disp_drv_t * disp_drv, lv_color_t * dest_buf, lv_coord_t dest_width,
//                    const lv_area_t * fill_area, lv_color_t color)
//{
//    /*It's an example code which should be done by your GPU*/
//    int32_t x, y;
//    dest_buf += dest_width * fill_area->y1; /*Go to the first line*/
//
//    for(y = fill_area->y1; y <= fill_area->y2; y++) {
//        for(x = fill_area->x1; x <= fill_area->x2; x++) {
//            dest_buf[x] = color;
//        }
//        dest_buf+=dest_width;    /*Go to the next line*/
//    }
//}


#else /*Enable this file at the top*/

/*This dummy typedef exists purely to silence -Wpedantic.*/
typedef int keep_pedantic_happy;
#endif

5.打开工程文件,添加连个组 lvgl/src 和 lvgl/port ,将各个C文件导入工程。一些字体文件(font)和 extra 内的文件,gpu文件可不用添加,除非使用到。
6.定时器中断函数里加入lv_tick_inc(1);
/**
* [url=home.php?mod=space&uid=555622]@prototype[/url] TIM2_IRQnCallBack(uint8_t lparam)
*
* @param[in] ...
* [url=home.php?mod=space&uid=266161]@return[/url]         ...
*
* [url=home.php?mod=space&uid=247401]@brief[/url]           TIM2 module interrupt handler.
*                         TIM2中断处理函数.
*/
void TIM2_IRQnCallBack(uint8_t lparam)
{
        if (TIMER_GetIntFlag(TIMER2))
    {
        
                g_ctimeflag=1;
        lv_tick_inc(1);
        }
    TIMER_ClrIntFlag(TIMER2);
}


6.在需要的地方添加头文件(如main.c)
#include "lvgl.h"
#include "lv_port_disp.h"

程序开头加入
lv_init();                                                        
    lv_port_disp_init();
然后在主函数的死循环或者低优先级任务中加入lv_task_handler();

这样就可以正常使用了。
用的屏幕比较小,不好发挥这个GUI的长处,随便弄些看看效果。在大屏中,这个GUI效果很不错。总体上比emWin好看。





使用特权

评论回复

相关帖子

沙发
daichaodai| | 2021-8-13 21:06 | 只看该作者
不错,改天也来玩玩。

使用特权

评论回复
板凳
marginer| | 2021-8-20 16:43 | 只看该作者
硬件上是透过什么连接和控制的。

使用特权

评论回复
评论
linguanghua 2021-8-20 17:38 回复TA
SPI接口的LCD屏,连线。 
地板
zsm123| | 2021-8-28 20:52 | 只看该作者
麻烦问下,切屏速度如何? SPI 传输使用 DMA了吗?

另外,帖子中正文处“lv_port_disp.c”的修改源码好像显示异常, 麻烦修改下?
@linguanghua

使用特权

评论回复
评论
linguanghua 2021-9-1 16:15 回复TA
源码贴上了。 其实这个GUI移植是最容易的。比起EMWIN,GUIX这些。 LVGL现在就差在没有上位机进行布局。 
5
单片小菜| | 2021-9-1 09:31 | 只看该作者
这个界面确实很棒,改天我也试试,看看怎么搞的。

使用特权

评论回复
6
kkzz| | 2021-9-1 19:42 | 只看该作者
芯片最低要求是什么?   

使用特权

评论回复
7
hudi008| | 2021-9-1 19:43 | 只看该作者
这个mcu是256kb吗      

使用特权

评论回复
8
lzmm| | 2021-9-1 19:43 | 只看该作者
LVGL提供了使用易于使用的图形元素   

使用特权

评论回复
9
minzisc| | 2021-9-1 19:43 | 只看该作者
LVGL中文教程有吗   

使用特权

评论回复
10
selongli| | 2021-9-1 19:44 | 只看该作者
littlevgl是一个小型开源嵌入式 GUI 库  

使用特权

评论回复
11
fentianyou| | 2021-9-1 19:45 | 只看该作者
研究一下例程和源码。  

使用特权

评论回复
12
xiaoyaodz| | 2021-9-1 19:45 | 只看该作者
设计UI界面太难了   

使用特权

评论回复
13
febgxu| | 2021-9-1 19:46 | 只看该作者
主要参考资料有吗   

使用特权

评论回复
14
sdlls| | 2021-9-1 19:47 | 只看该作者
全库采用纯 c 语言开发  

使用特权

评论回复
15
pixhw| | 2021-9-1 19:47 | 只看该作者
刷新的速度快吗   

使用特权

评论回复
16
selongli| | 2021-9-1 19:48 | 只看该作者
7.0版本的改动还是比较大的  

使用特权

评论回复
17
minzisc| | 2021-9-1 19:48 | 只看该作者
LVGL爱好者提供资料   

使用特权

评论回复
18
lzmm| | 2021-9-1 19:48 | 只看该作者
lvgl官方的教程是英文的  

使用特权

评论回复
19
hudi008| | 2021-9-1 19:48 | 只看该作者
刷新的速度怎么样   

使用特权

评论回复
20
kkzz| | 2021-9-1 19:48 | 只看该作者
占用多大的空间呢      

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

25

主题

214

帖子

4

粉丝