【ESP32】打造全网最强esp-idf基础教程——11.LVGL移植(基于ST7789芯片)

LVGL移植(基于ST7789芯片)

       风吹又日晒的打工日暂且告一段落,又到本公主的周末闲暇时光,在琐碎的日子里发发我的博客,看到有那么多支持我的小伙伴们点赞,心里乐开了花❀话不多说,且看以下:

一、前言
       本课内容涵盖了SPI、LCD、LVGL知识,每一个点单独来讲都是比较丰富的内容,尤其是LVGL,LVGL(Light and Versatile Graphics Library)是一个开源的图形用户界面(GUI)库,专为嵌入式系统设计,旨在提供轻量级、高度可移植、灵活且易于使用的图形界面解决方案。该库支持在不同的操作系统、微控制器以及图形加速器上运行,非常适合资源有限的嵌入式设备,其源码较多,功能较为庞大,可以单独的开一门课程去讲。那么本节课只涉及到LVGL的移植、SPI和LCD驱动接口的使用、以及demo演示。
       本节课内容也不少,因为SPI、LCD、LVGL显示三者在这节课中关系密切,因此我这边合起来一起描述。

二、LVGL源码获取和移植
       大家可以从https://github.com/lvgl/lvgl.git上获取LVGL最新的源码,LVGL目前最新的源码已更新到9.X,不同的版本之间接口基本难以兼容,因此我们需要选定一个版本,在这个版本基础上再去开发我们的显示程序,在本例程中使用的是8.3.10版本。大家先看esp32-board/display目录结构是这样的:

       被我标红的就是lvgl仓库的源码,目前我用git子仓库的形式引入,里面的内容我没有改动,只是把版本切换到了8.3.10,同时大家可能注意到,lvgl是以组件形式引入到这个工程的(目录解析具体可看第3个教程),路径在display/components/lvgl,另外我们也添加了一个bsp组件,bsp组件中用于存放与板相关的代码,我们把lvgl移植相关的代码也放在这里,具体的移植代码位于lv_port.c中。现在我们看下lv_port.c中具体有什么内容。
       先看一下与LVGL显示直接相关的初始化函数 

/**
 * @brief 注册LVGL显示驱动
 *
 */
static void lv_port_disp_init(void)
{
    static lv_disp_draw_buf_t draw_buf_dsc;
    size_t disp_buf_height = 40;

    /* 必须从内部RAM分配显存,这样刷新速度快 */
    lv_color_t *p_disp_buf1 = heap_caps_malloc(LCD_WIDTH * disp_buf_height * sizeof(lv_color_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA);
    lv_color_t *p_disp_buf2 = heap_caps_malloc(LCD_WIDTH * disp_buf_height * sizeof(lv_color_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA);
    ESP_LOGI(TAG, "Try allocate two %u * %u display buffer, size:%u Byte", LCD_WIDTH, disp_buf_height, LCD_WIDTH * disp_buf_height * sizeof(lv_color_t) * 2);
    if (NULL == p_disp_buf1 || NULL == p_disp_buf2) {
        ESP_LOGE(TAG, "No memory for LVGL display buffer");
        esp_system_abort("Memory allocation failed");
    }
    /* 初始化显示缓存 */
    lv_disp_draw_buf_init(&draw_buf_dsc, p_disp_buf1, p_disp_buf2, LCD_WIDTH * disp_buf_height);
    /* 初始化显示驱动 */
    lv_disp_drv_init(&disp_drv);
    /*设置水平和垂直宽度*/
    disp_drv.hor_res = LCD_WIDTH;
    disp_drv.ver_res = LCD_HEIGHT;
    /* 设置刷新数据函数 */
    disp_drv.flush_cb = disp_flush;
    /*设置显示缓存*/
    disp_drv.draw_buf = &draw_buf_dsc;
    /*注册显示驱动*/
    lv_disp_drv_register(&disp_drv);
}

       在LVGL中,要想显示内容,首先得告诉LVGL你的显示驱动信息,显示驱动信息包含显示刷新缓存、显示屏的宽高、显示输出函数这三个信息。 

       lv_disp_draw_buf_init函数用于初始化显示缓存,把用户定义的缓存设置到draw_buf_dsc显示缓存描述结构体上,这里要注意,我们使用esp-idf内存管理接口heap_caps_malloc申请的缓存一定要用MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA修饰,因为SPI传输RGB数据用的是DMA方式,这种方式无法应用于外部PSRAM,只能从内部IRAM进行申请。

       lv_disp_drv_init函数用于按默认配置初始化一个显示驱动disp_drv。 

       之后我们对disp_drv这个驱动进行设置,包括显示宽高、缓存、显示数据输出函数,显示数据输出函数disp_flush是需要我们实现的,当LVGL进行完界面的绘画后,最终是要调用这个函数将RGB显示数据输出到LCD屏上,实现如下:

 

/**
 * @brief 写入显示数据
 *
 * @param disp_drv  对应的显示器
 * @param area      显示区域
 * @param color_p   显示数据
 */
static void disp_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
{
    (void) disp_drv;
    st7789_flush(area->x1, area->x2 + 1, area->y1,area->y2 + 1, color_p);
}

       在disp_flush函数中,实际是调用了st7789驱动里面的刷新函数,将数据写入到st7789中,关于st7789的驱动我们在后面一节会讲到。 

      最后调用lv_disp_drv_register把这个显示驱动注册到LVGL中。
除了要设置显示

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值