ESP32 ESP-IDF LVGL8.3.3移植

news2024/9/22 21:17:57

陈拓 2022/11/27-2022/12/10

1. 概述

在《ESP32 ESP-IDF TFT-LCD(ST7735 128x160) LVGL演示》

ESP32 ESP-IDF TFT-LCD(ST7735 128x160) LVGL演示_晨之清风的博客-CSDN博客_esp32 tftlcd在ESP32开发框架ESP-IDF中用LVGL库驱动TFT-LCD(ST7735 128x160) 显示屏演示GUIhttps://blog.csdn.net/chentuo2000/article/details/126668088?spm=1001.2014.3001.5502

和《ESP32 ESP-IDF LVGL ST7789 演示lv_demo_music》

ESP32 ESP-IDF LVGL ST7789 演示lv_demo_music_晨之清风的博客-CSDN博客_espidf lvgl例程在ESP32的ESP-IDF开发环境下移植LVGL,配置ST7789 演示lv_demo_musichttps://blog.csdn.net/chentuo2000/article/details/126807644?spm=1001.2014.3001.5501

两篇文章中,我们演示了LVGL官方ESP32移植项目https://github.com/lvgl/lv_port_esp32

该项目使用使用的LVGL 7.9版本。

本文在此基础上移植LVGL8.3.3。

下面的例子中任然使用前面两篇文章中使用的ST7735和ST7789显示屏。

2. 构建ESP32 ESP-IDF开发环境

首先构建ESP32 ESP-IDF开发环境,可用参考《Ubuntu构建ESP32 ESP-IDF开发环境(简约版)》

https://blog.csdn.net/chentuo2000/article/details/128034585?spm=1001.2014.3001.5502

3. LVGL官方文档查看

https://docs.lvgl.io/master/get-started/platforms/espressif.html

LVGL可作为标准ESP-IDF组件使用和配置。

  • ESP32的LVGL演示项目

我们创建了lv_port_esp32(https://github.com/lvgl/lv_port_esp32),这是一个使用ESP-IDF和LVGL来展示demos (https://github.com/lvgl/lvgl/tree/master/demos)中的一个演示的项目。您可以将项目配置为许多受支持的显示控制器和目标芯片之一。

请参阅lvgl_esp32_drivers(https://github.com/lvgl/lvgl_esp32_drivers)存储库,以获取支持的显示器和独立触摸控制器和目标的完整列表。

  • 在ESP-IDF项目中使用LVGL

ESP-IDF v4.1及以上版本。

查看我的ESP-IDF版本:

get_idf

idf.py --version

  • 获取LVGL

只需将LVGL克隆到project_root/components目录中,它就会自动集成到项目中。

  • 配置

在项目根目录中使用idf.py menuconfig命令配置LVGL。

  • 在ESP-IDF项目中使用lvgl_esp32_drivers。

您还可以将lvgl_esp32_drivers添加为“组件”。该组件应位于项目根目录中名为“components”的目录中,和lvgl目录并列。

4. 创建工程项目

  • 复制项目模板

mkdir ~/esp442

cd ~/esp442/

cp -r ~/esp442/esp-idf/examples/get-started/sample_project/ ./esp32_lvgl833

  • 获取LVGL

cd esp32_lvgl833

mkdir components

cd components

  • 下载LVGL最新版本

https://github.com/lvgl/lvgl/tags

git clone -b v8.3.3 https://github.com/lvgl/lvgl.git

  • 获取lvgl_esp32_drivers

git clone https://github.com/lvgl/lvgl_esp32_drivers.git

  • 项目目录结构

其中:Makefile和component.mk可用删除。

5. 编译

  • 刷新esp-idf环境

get_idf

  • 设定目标芯片

idf.py set-target esp32

删除build目录:

rm -r build/

idf.py set-target esp32

  • 配置项目

idf.py menuconfig

1) 将闪存设置为4MB

2) 不选择开发板

3) 选择显示屏控制芯片

或者

4) SPI总线选择

默认是SPI2_HOST。

ESP32有4组SPI外设。

SPI0和SPI1在内部用于访问ESP32所连接的闪存。

SPI2和SPI3是通用SPI控制器,分别称为HSPI和VSPI(LVGL 默认是HSPI)。它们向用户开放。

SPI2和SPI3的默认引脚:

这些引脚是可以重新映射的,所以下面我们的接线和默认并不相同。

在我们的实验中没有使用MISO,所以下面的接线表中没有MISO。

5) 定义引脚

接线表:

ST7735或ST7789         ESP32

GND                              GND

VCC                              3V3

SCL                              IO14(CLK)

SDA                              IO27(MOSI)

RES                              IO16

DC                               IO17(DC)

CS                                IO25

BLK                              IO26

背光控制:

6) 屏幕方向

ST7735横屏

ST7789横屏

7) 设置显示字符大小

对于ST7735因为屏幕小,选用更小的字号12,默认是14。

对于ST7789使用默认14号字:

8) 交换16位颜色的2个字节

ST7735和ST7789的颜色深度是16位,选择Color depth. (16:RGB565),颜色值用2字节表示,ESP32是小端Little Endian模式,先发送低位字节,如果颜色失真,可以选交换颜色值的高低字节。

哪些显示屏需要交换颜色字节,在lvgl_esp32_drivers/README.md中有说明:

9) 不使用定制的lv_conf.h,这是默认

保存,退出。

  • 编译项目

idf.py build

编译警告:

如果开发板(例如M5StickC)上有AXP192电池管理单元,需要在idf.py menuconfig配置中启用:

我们的板子上没有AXP192,所以忽略这些警告。或者删除

~/esp442/esp32_lvgl833/components/lvgl_esp32_drivers/lvgl_tft/st7735s.c

中相关代码。

编译错误:

/home/ct/esp442/esp32_lvgl833/components/lvgl_esp32_drivers/lvgl_helpers.h中添加宏定义:

对于ST7735

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

#define LV_HOR_RES_MAX 160
#define LV_VER_RES_MAX 128
#define SPI_HOST_MAX 3

再修改st7735s.h以适合我们的显示屏

~/esp/lv_port_esp32/components/lvgl_esp32_drivers/lvgl_tft/st7735s.h

#define ST7735_GREENTAB160x80 // For 160 x 80 display (BGR, inverted, 26 / 1 offset)
#define COLSTART            0 //26
#define ROWSTART            0 //1

原来的参数是针对160x80写的,要将COLSTART和ROWSTART都改为0。

对于ST7789只需要修改:

#define LV_HOR_RES_MAX 320
#define LV_VER_RES_MAX 240
#define SPI_HOST_MAX 3

其他地方都不用动。

再编译:

idf.py build

编译通过,这样移植就完成了。

6. LVGL演示

为了看LVGL的效果,我们以

https://github.com/lvgl/lv_port_esp32/tree/master/main/main.c

为例进行演示,其中的代码是针对LVGL 7.9版本写的,我们需要做一些修改。

6.1 基本演示

  1. 修改main.c

现在的main.c是空的:

#include <stdio.h>

void app_main(void)
{

}

用下面的代码替换:

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "lvgl.h"
#include "freertos/semphr.h"
#include "esp_system.h"
#include "lvgl_helpers.h"

/*********************
 *      DEFINES
 *********************/
#define LV_TICK_PERIOD_MS 1

/**********************
 *  STATIC PROTOTYPES
 **********************/
static void lv_tick_task(void *arg);
static void guiTask(void *pvParameter);
static void create_demo_application(void);

/**********************
 *   APPLICATION MAIN
 **********************/
void app_main(void)
{
    // xTaskCreate(guiTask, "gui", 4096*2, NULL, 1, NULL);
    // xTaskCreatePinnedToCore(guiTask, "gui", 4096*2, NULL, 1, NULL, 1);
    /* NOTE: When not using Wi-Fi nor Bluetooth you can pin the guiTask to core 0 */
    xTaskCreatePinnedToCore(guiTask, "gui", 4096*2, NULL, 0, NULL, 1);
}

/* Creates a semaphore to handle concurrent call to lvgl stuff
 * If you wish to call *any* lvgl function from other threads/tasks
 * you should lock on the very same semaphore! */
SemaphoreHandle_t xGuiSemaphore;

static void guiTask(void *pvParameter)
{
    (void) pvParameter;
    xGuiSemaphore = xSemaphoreCreateMutex();

    lv_init();

    /* Initialize SPI or I2C bus used by the drivers */
    lvgl_driver_init();

    lv_color_t *buf1 = heap_caps_malloc(DISP_BUF_SIZE * sizeof(lv_color_t), MALLOC_CAP_DMA);
    assert(buf1 != NULL);
    /* Use double buffered when not working with monochrome displays */
    lv_color_t* buf2 = heap_caps_malloc(DISP_BUF_SIZE * sizeof(lv_color_t), MALLOC_CAP_DMA);
    assert(buf2 != NULL);
    static lv_disp_draw_buf_t disp_buf;
    uint32_t size_in_px = DISP_BUF_SIZE;
    /* Initialize the working buffer depending on the selected display. */
    lv_disp_draw_buf_init(&disp_buf, buf1, buf2, size_in_px);

    lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);
    disp_drv.hor_res = LV_HOR_RES_MAX;
    disp_drv.ver_res = LV_VER_RES_MAX;
    disp_drv.flush_cb = disp_driver_flush;
    disp_drv.draw_buf = &disp_buf;
    lv_disp_drv_register(&disp_drv);

    /* Create and start a periodic timer interrupt to call lv_tick_inc */
    const esp_timer_create_args_t periodic_timer_args = {
        .callback = &lv_tick_task,
        .name = "periodic_gui"
    };
    esp_timer_handle_t periodic_timer;
    ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer));
    ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, LV_TICK_PERIOD_MS * 1000));

    /* Create the demo application */
    create_demo_application();

    while (1)
    {
        /* Delay 1 tick (assumes FreeRTOS tick is 10ms */
        vTaskDelay(pdMS_TO_TICKS(10));
        lv_task_handler();

        /* Try to take the semaphore, call lvgl related function on success */
        if (pdTRUE == xSemaphoreTake(xGuiSemaphore, portMAX_DELAY)) {
            lv_task_handler();
            xSemaphoreGive(xGuiSemaphore);
       }
    }
}

static void create_demo_application(void)
{
    /* Get the current screen  */
    lv_obj_t * scr = lv_disp_get_scr_act(NULL);    
    /*Create a Label on the currently active screen*/
    lv_obj_t * label1 =  lv_label_create(scr);
    /*Modify the Label's text*/
    lv_label_set_text(label1, "Hello\nworld");
    /* Align the Label to the center
     * NULL means align on parent (which is the screen now)
     * 0, 0 at the end means an x, y offset after alignment*/
    lv_obj_align(label1, LV_ALIGN_CENTER, 0, 0);
}

static void lv_tick_task(void *arg) {
    (void) arg;

    lv_tick_inc(LV_TICK_PERIOD_MS);
}
  • 编译

idf.py build

  • 烧写项目

查看USB转串口设备:

ls -l /dev/ttyUSB*

修改权限:

sudo chmod 777 /dev/ttyUSB0

烧写:

idf.py -p /dev/ttyUSB0 -b 460800 flash

  • 启用监视器

idf.py monitor -p /dev/ttyUSB0

当示例正常运行时,将观察到以下输出:

  • ST7735屏显示

  • ST7789屏显示

6.2 examples演示lv_example_get_started_1.c

  • 选择一个例子lv_example_get_started_1.c进行测试

  • 配置项目

idf.py menuconfig

  • 修改main.c

添加头文件:

#include "examples/lv_examples.h"

修改create_demo_application函数

static void create_demo_application(void)
{
    lv_example_get_started_1();
}
  • 修改main目录下的 CMakelists.txt 
idf_component_register(SRCS "main.c" 
"../components/lvgl/examples/get_started/lv_example_get_started_1.c"                     
                    INCLUDE_DIRS ".")
  • 编译、烧写

idf.py build

idf.py -p /dev/ttyUSB0 -b 460800 flash

  • ST7735显示

按钮的颜色是反转的(蓝光与黄光互为补色),字符是正常的,因为字符颜色是白色,高低字节相同,高低字节交换不受影响。

有些文章说在设置中选中Invert colors in display,经过测试不行。

我的解决方法见《ESP32 ESP-IDF LVGL ST7735颜色修正》

ESP32 ESP-IDF LVGL8.3.3 ST7735颜色修正_晨之清风的博客-CSDN博客ESP32 ESP-IDF LVGL8.3.3 ST7735颜色修正。https://blog.csdn.net/chentuo2000/article/details/128269784?spm=1001.2014.3001.5502这是颜色修正后的效果:

  • ST7789显示

ST7789显示的颜色是正常的。

6.3 examples演示lv_example_btnmatrix_2.c

  • 选择另一个例子lv_example_btnmatrix_2.c进行测试

~/esp442/esp32_lvgl833/components/lvgl/examples/widgets/btnmatrix/lv_example_btnmatrix_2.c

  • 修改main.c

添加头文件:

#include "examples/lv_examples.h"

修改create_demo_application函数

static void create_demo_application(void)
{
    lv_example_btnmatrix_2();
}
  • 修改main目录下的 CMakelists.txt 
idf_component_register(SRCS "main.c" 
"../components/lvgl/examples/get_started/lv_example_get_started_1.c" 
"../components/lvgl/examples/widgets/btnmatrix/lv_example_btnmatrix_2.c" 
"../components/lvgl/examples/assets/img_star.c"                    
                    INCLUDE_DIRS ".")
  • 编译、烧写

idf.py build

idf.py -p /dev/ttyUSB0 -b 460800 flash

  • 经过颜色校正的ST7735S显示

对比下面ST7789的显示,小部件(widget)的颜色都对了,五角星图像的颜色还是反转的。如果有需求可以参照《ESP32 ESP-IDF LVGL ST7735颜色修正》一文的方法对图像进行颜色修正。

  • ST7789显示

6.4 demos 演示

  • 配置项目

idf.py menuconfig

选择Show some widget和Enable slide show

  • 修改main.c

添加头文件:

#include "demos/lv_demos.h"
  • 修改create_demo_application函数
static void create_demo_application(void)
{
    #if defined CONFIG_LV_USE_DEMO_WIDGETS
        lv_demo_widgets();
    #elif defined CONFIG_LV_USE_DEMO_KEYPAD_AND_ENCODER
        lv_demo_keypad_encoder();
    #elif defined CONFIG_LV_USE_DEMO_BENCHMARK
        lv_demo_benchmark();
    #elif defined CONFIG_LV_USE_DEMO_STRESS
        lv_demo_stress();
    #else
        #error "No demo application selected."
    #endif
}
  • 修改main目录下的 CMakelists.txt 
idf_component_register(SRCS "main.c" 
"../components/lvgl/demos/widgets/lv_demo_widgets.c" 
"../components/lvgl/demos/widgets/assets/img_lvgl_logo.c" 
"../components/lvgl/demos/widgets/assets/img_demo_widgets_avatar.c"
"../components/lvgl/demos/widgets/assets/img_clothes.c"
                    INCLUDE_DIRS ".")
  • 编译

idf.py build

内存不足,无法运行lv_demo_widget。请将LV_MEM_SIZE设置为至少38KB(38ul*1024ul)。建议使用48KB。

再编译,成功。

  • 烧写

idf.py -p /dev/ttyUSB0 -b 460800 flash

  • 经过颜色校正的ST7735S显示

  • ST7789显示

6.5 其他的官方示例的演示类似。

参考文档

  1. ESP32-IDF Cmake编写要点
    https://blog.csdn.net/qq_43940227/article/details/120893146
  2. 如何在ESP32-C3上添加自己的工程
    https://www.pudn.com/news/6228e06b9ddf223e1ad2e675.html
  3. ESP32,Linux下使用ESP-IDF添加自己的组件库(components)
    https://blog.csdn.net/weixin_41683042/article/details/120698215

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/79564.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

游戏开发46课 性能优化5

3. CPU优化 性能优化最主要的一部分工作是CPU&#xff0c;CPU性能优化好了&#xff0c;离目标就成功了一半。 3.1 缓存计算结果 缓存计算是空间换时间的经典应用&#xff0c;它适用于那些耗费大量CPU计算而计算结果无需每帧变化的逻辑。实现伪代码&#xff1a; std::map<…

【Redis场景1】用户登录注册

细节回顾&#xff1a; 关于cookie和session不熟悉的朋友&#xff1b; 建议阅读该博客&#xff1a;https://www.cnblogs.com/ityouknow/p/10856177.html 执行流程&#xff1a; 在单体模式下&#xff0c;一般采用这种模式来存储&#xff0c;传递、认证用户登录、注册等信息&…

阿里巴巴最新推出王者笔记:“Spring MVC 源码与实践”

前言&#xff1a; Spring MVC 是 Spring 框架中用于 Web 应用快速开发的一个模块。Spring MVC 的 MVC 是 Model-View-Contoller 的缩写。它是一个广泛应用于图形化用户交互开发中的设计模式&#xff0c;不仅常见于 Web 开发&#xff0c;也广泛应用于如 Swing 和 JavaFX 等桌面…

Java知识要点

第1章 Java概述 重要特性&#xff1a; Write Once Run Anyway 简单性&#xff1a;相比C移除指针、运算符重载、多重继承等&#xff0c;垃圾自动回收。 平台无关性&#xff1a;Java引进虚拟机&#xff08;JVM&#xff0c;Java Virtual Machine&#xff09;概念。 安全性&am…

论文推荐:Rethinking Attention with Performers

重新思考的注意力机制&#xff0c;Performers是由谷歌&#xff0c;剑桥大学&#xff0c;DeepMind&#xff0c;和艾伦图灵研究所发布在2021 ICLR的论文已经超过500次引用 传统的Transformer的使用softmax 注意力&#xff0c;具有二次空间和时间复杂度。Performers是Transformer…

常用射频器件性能指标

IFM&#xff08;Instantaneous FrequencyMeasurement&#xff09;&#xff1a;瞬时测频接收机&#xff1b; SOC&#xff08;System on Chip&#xff09;&#xff1a;片上系统&#xff0c;可独立实现接收机功能&#xff1b; AIU&#xff1a;前端 一、放大器关键参数 1.1 -1dB压…

如何选择好的软件测试技术?

软件测试技术是指测试软件或软件一部分的方法或方式。每种测试技术都有其自身的优势。不同的技术针对不同类型的缺陷。因此&#xff0c;说一种技术是最好的是错误的。根据软件及其要求&#xff0c;一种测试技术可能比另一种更适合用于该目的。有时&#xff0c;结合使用不同的测…

安卓APP源码和设计报告——魔幻相机

课程设计报告书 Android大作业 学 院 计算机科学与工程学院 专 业 计算机科学与技术一班 学生姓名 小组成员 学生学号 指导教师 课程编号 课程学分 起始日期 教师评语 教师签名&#xff1a;日期&#xff1a; 成绩评定 备注 Android大作业 魔幻相机 一、选题背景 据统计&am…

[激光原理与应用-47]:《焊接质量检测》-4-普雷茨特激光焊接过程监控系统LWM分析

目录 第1章 激光焊接过程监控系统LWM概述 第2章 产品特性与功能 2.1 生产相关的信息 2.2 原始信息检测 2.3 焊接质量分析信息 2.4 缺陷报告与生产控制 2.5 LWM给客户带来的好处 2.6 适用范围 2.7 人机界面 (HMI) 第3章 焊接质量检测的原理 3.1 基本原理 3.2 技术规…

excel_阻止常数值串以科学计数法显示@数据分列@空格分隔符号分列数据

文章目录excel_阻止常数值串以科学计数法显示WPS设置某列的数据显示格式核心步骤数据-分列选择分割符设置文本类型收尾工作数据居中Office-Excelexcel_阻止常数值串以科学计数法显示 WPS 设置某列的数据显示格式 核心步骤 如果您的数据是普通数据,那么类型框里输入0就可以了…

太忙,没时间学?在职人员如何高效备考MBA?

对于很多在职人员来说&#xff0c;想要进一步深造提升学历&#xff0c;备考MBA无疑是个不错的选择。但近几年随着MBA考生人数的增长&#xff0c;其竞争也愈加激烈。因此想要取得好的成绩&#xff0c;成功上岸&#xff0c;不仅仅需要持续不断的努力&#xff0c;时间的科学管理和…

机器人与视觉,基于TCP(工具坐标)偏移

基于工具坐标系的移动偏转。 基于TCP旋转的特点在于&#xff0c;具有1个固定端点&#xff0c;多个活动端的特点。 我们在建立TCP左边偏移的时候&#xff0c;可以将2个点近似的模拟在同一个坐标系下 基于TCP偏转的特点在于&#xff0c;工作的时候&#xff0c;示教点与工作点的位…

CSS -- 03. CSS盒子模型

文章目录盒子模型1 盒子模型1.1 看透网页的本质1.2 盒子模型组成1.3 边框1.4 表格的细线边框1.5 边框会影响盒子实际大小1.6 内边距&#xff08;padding&#xff09;1.7 外边距&#xff08;margin&#xff09;1.8 外边距合并1.9 清除内外边距2 圆角边框3 盒子阴影4 文字阴影盒子…

netfilteriptables探讨(4)——nat的实现与使用

在之前的几篇文章中&#xff0c;我们讨论了netfilter与iptables的实现原理与基本用法。在netfilter&iptables的各种使用场景中&#xff0c;nat是最常用也是最复杂的用法之一。许多常用的网络使用模式都是通过nat iptables规则实现的&#xff0c;例如docker默认的bridge网络…

Netty_06_手写RPC基础版(实践类)

文章目录一、前言二、整体运行三、客户端和服务端3.1 客户端3.2 服务端3.3 RpcServerInitializer和RpcClientInitializer四、小结一、前言 常用的rpc框架&#xff1a;dubbo thrift gRPC rpc定义&#xff1a;remote proceducer call rpc目的/解决的问题&#xff1a; 像调用本地…

Nginx实战应用-负载均衡

在上篇文章的基础上我们再创建两个服务&#xff0c;三个服务的端口分别是 8081 8082 8083. 2.Nginx配置 upstream块 upstream name{…} upstream gupao{ server 192.168.12.1:8081; server 192.168.12.1:8082; server 192.168.12.1:8083; } server { location / { pr…

平均月薪15k+?自动化测试工程师?3个月教你从“点工”蜕变为“码农”

前言 一、自动化测试工程师平均收入【看图&#xff08;来自职友集&#xff09;】 基本收入都在15k左右&#xff0c;随着技术的越来越牛逼工资也就会越来越高。 我的职业生涯开始和大多数测试人一样&#xff0c;刚开始接触都是纯功能界面测试。那时候在一家电商公司做测试&…

[附源码]计算机毕业设计基于vue+mysql开发的考试系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【PAT甲级 - C++题解】1092 To Buy or Not to Buy

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 &#x1f4da;专栏地址&#xff1a;PAT题解集合 &#x1f4dd;原题地址&#xff1a;题目详情 - 1092 To Buy or Not to Buy (pintia.cn) &#x1f511;中文翻译&#xff1a;买还是不买 &#x…

JAVA中的运算符-关系运算符

文章目录0 写在前面1 关系运算符说明2 举例3 写在最后0 写在前面 JAVA包含丰富的关系运算符&#xff0c;这些关系运算符最终结果一定是boolean类型。即两个结果&#xff1a;true false 1 关系运算符说明 符号说明ab,判断a和b的值是否相等&#xff0c;成立为true&#xff0c;…