首页 > 其他分享 >基于IDF的ESP32S3-LVGL DEMO移植

基于IDF的ESP32S3-LVGL DEMO移植

时间:2024-09-21 15:47:18浏览次数:8  
标签:disp DEMO void ESP32S3 drv lv key IDF LVGL

简介

ESP32-32出色的性价比,较好的性能与内存空间,可以好利用来完成GUI显示库的加载

LVGL

LVGL是一款比较流行的致力于MCU与MPU创建漂亮UI的嵌入式图形库,免费且开源。

硬件

硬件采用的是正点原子的ESP32-S3
屏幕使用的是SPI通信方式,配合IO口控制(RST,A0),来实现LCD屏幕的驱动

移植步骤

LVGL移植总的步骤主要是如下几步
1.调用lv_init();
2.初始化驱动
3.注册显示与输入驱动,显存的配置,显示响应回调函数的响应
4.lv_tick_inc(x) 在中断中定时更新,x设定取决于lv_tick_inc的调用频率
5.lv_timer_handler,定时调用,完成LVGL的响应(更新LVGL的响应)

具体示例

拷贝一个可以正常驱动LCD的工程

拷贝LVGL(V8.3.0)代码至工程,ESP32需要在指定的路径components下

由于ESP32并不需要去修改lv_conf.h这个文件来配置LVGL,可以通过设置项来修改LVGL的配置,具体的配置机制原理未深入了解

配置LVGL

在默认的设置下勾选MUSIC DEMO,由于MUSCI DEMO中还用到了其他字体,还需要勾选 Montserrat 12与Montserrat 16这两种字体


此时编译工程,应该是可以编译通过

移植LVGL相关代码

SemaphoreHandle_t xGuiSemaphore;

void lvgl_demo(void)
{
    lv_init();            //LVGL初始化前都需要调用
    lv_port_disp_init();  //显示驱动的移植,初始化及配对,输出  
    lv_port_indev_init(); //输入驱动的移植

    xGuiSemaphore = xSemaphoreCreateMutex();

    const esp_timer_create_args_t lvgl_tick_timer_args = {
        .callback = &increase_lvgl_tick,
        .name = "lvgl_tick"
    };
    esp_timer_handle_t lvgl_tick_timer = NULL;
    ESP_ERROR_CHECK(esp_timer_create(&lvgl_tick_timer_args, &lvgl_tick_timer));
    ESP_ERROR_CHECK(esp_timer_start_periodic(lvgl_tick_timer, 1 * 1000)); //创建定时器,更新LVGL的内部时钟基准

    lv_demo_music();
    while(1)
    {
        if( pdTRUE == xSemaphoreTake(xGuiSemaphore, portMAX_DELAY))
        {
            lv_timer_handler(); //定时调用,更新LVGL的实现
            xSemaphoreGive(xGuiSemaphore);
        }
        
        vTaskDelay(pdMS_TO_TICKS(5));
    }
}

static void increase_lvgl_tick(void *arg)
{
    lv_tick_inc(1);
}

显示初始化与绑定代码

void lv_port_disp_init(void)
{
    void *buf1 = NULL;

    buf1 = heap_caps_malloc(lcd_self.width * 10 * sizeof(lv_color_t), MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); //申请显存

    static lv_disp_draw_buf_t disp_buf;
    lv_disp_draw_buf_init(&disp_buf, buf1, NULL, lcd_self.width * 10); //绑定显存,显存绑定有多种形式,这是一种开销最小的单显存设置

    static lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);

    disp_drv.hor_res = lcd_self.width; //屏幕宽度
    disp_drv.ver_res = lcd_self.height; //屏幕高度

    disp_drv.flush_cb = lvgl_disp_flush_cb;

    disp_drv.draw_buf = &disp_buf;

    lv_disp_drv_register(&disp_drv); //初始化显示屏幕尺寸,并绑定屏幕更新函数
}

static void lvgl_disp_flush_cb(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map)
{
    lcd_color_fill(area->x1, area->y1, area->x2, area->y2, (uint16_t*)color_map);//显示屏区域更新像素点颜色,像素颜色在数组中
    lv_disp_flush_ready(drv); //发送更新完毕,这一句代码必须要有
}

输出驱动里面如果是空的也可以完成显示的移植,只是没有输入功能
demo示例,参考的正点原子提供的代码,有没有都不影响MUSIC DEMO的显示
MUSCI DEMO对这几个按键也没有响应,加上了,也无法判断是否已正常工作

void lv_port_indev_init(void)
{
    static lv_indev_drv_t indev_drv;

    keypad_init();

    lv_indev_drv_init(&indev_drv);
    indev_drv.type = LV_INDEV_TYPE_KEYPAD;
    indev_drv.read_cb = keypad_read;
    indev_keypad = lv_indev_drv_register(&indev_drv);
}

uint32_t g_last_key = 0;

void keypad_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data)
{
    uint32_t act_key = keypad_get_key();

    if(act_key != 0)
    {
        data->state = LV_INDEV_STATE_PR;

        switch(act_key)
        {
            case KEY0_PRES:
                act_key = LV_KEY_RIGHT;
                break;
            case KEY1_PRES:
                act_key = LV_KEY_NEXT;
                //back_act_key = KEY1_PRES;
                break;
            case KEY2_PRES:
                act_key = LV_KEY_LEFT;
                break;
            case KEY3_PRES:
                act_key = LV_KEY_ENTER;
                break;
            default:
                break;
        }

        g_last_key = act_key;
    }
    else
    {
        data->state = LV_INDEV_STATE_REL;
        g_last_key = 0;
    }

    data->key = g_last_key;
}

uint32_t keypad_get_key(void)
{
    return xl9555_key_scan(0);
}

显示效果

V9.1.0移植

大体步骤与V8.3.0一致,期间出了一些问题,在这里也记录下

屏幕驱动API有些变化,更新程序的形参考声明有所变化,直接转换成uint16_t*的16位RGB565颜色也可以正常显示,暂时没有深究具体原因

void lv_port_disp_init(void)
{
    void *buf1 = NULL;
    buf1 = heap_caps_malloc(lcd_self.width * 10 * 4, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);

    lv_display_t *disp = lv_display_create(lcd_self.width, lcd_self.height);
    lv_display_set_flush_cb(disp, lvgl_disp_flush_cb);

    lv_display_set_buffers(disp, buf1, NULL, lcd_self.width * 10 * 4, LV_DISPLAY_RENDER_MODE_PARTIAL);
}

static void lvgl_disp_flush_cb(lv_disp_t *drv, const lv_area_t *area, uint8_t *px_map)
{
    lcd_color_fill(area->x1, area->y1, area->x2, area->y2, (uint16_t*)px_map);
    lv_disp_flush_ready(drv);
}

无法正常显示,提示栈溢出

原因在于任务栈太小了,导致任务运行出错,增大任务栈即可正常工作。LVGL的使用,相对来说使用的STACK较深,系统默认的配置就不太够用

总结

LVGL需要配置显存跟内存,同时也需要考虑任务栈的问题,使用的过程中一定也会遇到很多问题,资料相对较少要自己多加摸索。
经过上述步骤 LVGL可以在ESP32上面运行DEMO,不过这个离会用LVGL还有一定的距离。
还需要查看更多的LVGL资料,以及ESP32-IDF编程的资料,才能进一步熟悉并使用。

标签:disp,DEMO,void,ESP32S3,drv,lv,key,IDF,LVGL
From: https://www.cnblogs.com/stupidpeng/p/18374386

相关文章

  • WPF 数据绑定之ValidationRule数据校验综合Demo
    一、概述我们利用ValidationRule以及ErrorTemplate来制作一个简单的表单验证。二、Demo核心思想:我们在ValidationRule中的Validate函数中进行验证,然后将验证结果存放至一个预先定义好的全局资源中,这样其他控件就可以根据验证结果来进行相应的处理,代码参见以下:usingSystem......
  • OSG开发笔记(三十):OSG加载动力学仿真K模型文件以及测试Demo
    前言  Osg需要打开模型文件,但是遇到显示动力学仿真的K模型文件,.k文件是一种描述材料属性的文件,比如密度、弹性模量等,该模型文件不是常规中间开放格式,无法直接支持,需要自定义解析并且重建三维模型。<br>Demo  实际非常流程,因为视频转gif导致部分看起来不行:      <......
  • Android使用LiquidFun物理引擎实现果冻碰撞效果
    一、效果展示Android使用LiquidFun物理引擎实现果冻碰撞效果二、LiquidFun物理引擎简介LiquidFun是一个由Google开发并开源的2D物理模拟库,它基于Box2D物理引擎,并扩展了流体模拟的功能。流体动力学模拟:LiquidFun提供了强大的流体动力学系统,可以模拟流体的行为,包括液体......
  • TF-IDF(词频-逆文档词频)
    目录1.算法公式1.1TF(词频)1.2IDF(逆文档词频)2.算法使用2.1API使用2.2API工作3.参数详解3.1文档处理相关参数3.2词表构建相关参数3.3影响计算相关参数TF-IDF(TermFrequency–InverseDocumentFrequency)是一种用于信息检索与文本挖掘的常用技术。通过......
  • 任务系统demo
    usingSystem;usingSystem.Collections;usingSystem.Collections.Generic;usingSystem.Xml.Serialization;usingUnityEngine;namespaceeTaskHandleSystem{publicinterfaceITaskState{///<summary>///开始任务///......
  • Smartbi体验中心新增系列Demo,用户体验更丰富
    为进一步提升用户体验,让大家更直观地了解Smartbi产品在数据分析方面的功能优势,Smartbi体验中心近期新增了一系列Demo。这些更新旨在优化产品操作流程,并为用户提供更多真实场景下的应用参考。接下来,我们一起简要浏览此次体验中心的更新内容。新增[场景案例Demo]体验中心Demo新增【场......
  • demo:tvm优化resnet50 llvm后端cpu上推理
    这是一个完整的例子。使用预训练的resnet50模型,经过tvm优化调整,target=llvm,在cpu上进行推理。最后打印结果是1这个索引代表goldfish importonnxfromtvm.contrib.downloadimportdownload_testdatafromPILimportImageimportnumpyasnpimporttvm.relayasrel......
  • UniGUI的布局(结合官方自带DEMO)要点记录
    UniGUI的页面布局还是比较方便的,基本什么的排版都能搞好。但UniGUI的资料实在是太少,只能看到一些零星的资料,结合UniGUI官方自带的DEMO,本人将布局有关要点整理了一下,方便查阅,也供各位爱好者参考,不对之处,敬请指正。一、布局方式传统Delphi程序的布局方法通过将属性Align添加到......
  • 【GIS开发小课堂】写一个高德地图巡航功能的小DEMO
    介绍此项目使用vite为基础架构,内部实现均以typescript开发,可替换为自己的业务逻辑,并迁移到react,vue,umi等其他框架。通过调用高德地图的API和threejs的开发,实现了一个小鸭子(可替换为自己的模型)沿着规划路线行走,并使镜头跟随小鸭子前进的功能。该功能主要常见于外卖平台......
  • arraybag1arrayBagDemo1
    /**  AtestoftheconstructorsandthemethodsaddandtoArray,  asdefinedinthefirstdraftoftheclassArrayBag.  @authorFrankM.Carrano  @version4.0*/publicclassArrayBagDemo1{  publicstaticvoidmain(String[]args)  { ......