ESP-IDF移植lvgl 驱动 ST7789

文章目录

  • 1 前言
  • 2 准备
  • 3 移植LVGL
    • 3.1 工程准备
    • 3.2 修改 CMakeLists.txt文件编译 LVGL
    • 3.3 编译LVGL
  • 4 编译 ST7789 LCD驱动
  • 5 发现问题

1 前言

本教程开始学习 LVGL的,开始之前要把环境配置好,首先就需要移植 lvgl,使用的是 esp32 环境,使用的 LCD驱动IC是 ST7789,没有使用到触摸屏。

2 准备

组件下载地址

https://components.espressif.com/
  • 准备一个空的工程

  • 下载 esp_lvgl_port

    https://components.espressif.com/components/espressif/esp_lvgl_port
    
  • 下载 LVGL8.3.6

    https://components.espressif.com/components/lvgl/lvgl/versions/8.3.6~1?language=en
    

    下载位置

    在这里插入图片描述

这里说明一下:为什么使用手动下载,很多教程都是使用的是 idf_component.yml 这个文件进行配置,但是在下载 esp_lvgl_port 的时候,会自动下载 LVGL 8 的最新版,或者LVGL 9 的最新版,而且弄好以后,还需要重新吧远程的文件重新移动到本地文件,不然后面修改组件的代码,会编译报错。笔者想使用的是 LVGL 8.3.6,所以选择手动下载配置,

3 移植LVGL

3.1 工程准备

  • components 文件夹

main 文件夹 同级别 的目录下,新建一个 components 的文件夹,把刚刚下载好的两个文件移动到 components 目录下,并修改一个简单的文件夹名字,

在这里插入图片描述

3.2 修改 CMakeLists.txt文件编译 LVGL

esp_lvgl_Port 依赖于 LVGL,修改 esp_lvgl_Port -> CMakeLists.txt 文件

`lvgl_lvgl`改成 `lvgl``lvgl_lvgl`改成 "lvgl的文件夹名字"

在这里插入图片描述

3.3 编译LVGL

  • 编译成功

在这里插入图片描述

4 编译 ST7789 LCD驱动

在下载 esp_lvgl_Port 的时候,就会自动下载了 ST7789的驱动,如果不是 ST7789的驱动,那么需要自己去下载相关的驱动,下载地址也是

https://components.espressif.com/

搜索自己的 LCD驱动 IC 名称进行下载,放在 components 目录下即可。

  • main.c编写驱动代码
/** SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD** SPDX-License-Identifier: Apache-2.0*/#include "esp_err.h"
#include "esp_log.h"
#include "esp_check.h"
#include "driver/i2c.h"
#include "driver/gpio.h"
#include "driver/spi_master.h"
#include "esp_lcd_panel_io.h"
#include "esp_lcd_panel_vendor.h"
#include "esp_lcd_panel_ops.h"
#include "esp_lvgl_port.h"/* LCD size */
#define EXAMPLE_LCD_H_RES   (320)
#define EXAMPLE_LCD_V_RES   (240)/* LCD settings */
#define EXAMPLE_LCD_SPI_NUM         (SPI3_HOST)
#define EXAMPLE_LCD_PIXEL_CLK_HZ    (40 * 1000 * 1000)
#define EXAMPLE_LCD_CMD_BITS        (8)
#define EXAMPLE_LCD_PARAM_BITS      (8)
#define EXAMPLE_LCD_COLOR_SPACE     (ESP_LCD_COLOR_SPACE_BGR)
#define EXAMPLE_LCD_BITS_PER_PIXEL  (16)
#define EXAMPLE_LCD_DRAW_BUFF_DOUBLE (1)
#define EXAMPLE_LCD_DRAW_BUFF_HEIGHT (50)
#define EXAMPLE_LCD_BL_ON_LEVEL     (1)/* LCD pins */
#define EXAMPLE_LCD_GPIO_SCLK       (GPIO_NUM_7)
#define EXAMPLE_LCD_GPIO_MOSI       (GPIO_NUM_6)
#define EXAMPLE_LCD_GPIO_RST        (GPIO_NUM_48)
#define EXAMPLE_LCD_GPIO_DC         (GPIO_NUM_4)
#define EXAMPLE_LCD_GPIO_CS         (GPIO_NUM_5)
#define EXAMPLE_LCD_GPIO_BL         (GPIO_NUM_45)static const char *TAG = "EXAMPLE";/* LCD IO and panel */
static esp_lcd_panel_io_handle_t lcd_io = NULL;
static esp_lcd_panel_handle_t lcd_panel = NULL;/* LVGL display and touch */
static lv_display_t *lvgl_disp = NULL;static esp_err_t app_lcd_init(void)
{esp_err_t ret = ESP_OK;/* LCD backlight */gpio_config_t bk_gpio_config = {.mode = GPIO_MODE_OUTPUT,.pin_bit_mask = 1ULL << EXAMPLE_LCD_GPIO_BL};ESP_ERROR_CHECK(gpio_config(&bk_gpio_config));/* LCD initialization */ESP_LOGD(TAG, "Initialize SPI bus");const spi_bus_config_t buscfg = {.sclk_io_num = EXAMPLE_LCD_GPIO_SCLK,.mosi_io_num = EXAMPLE_LCD_GPIO_MOSI,.miso_io_num = GPIO_NUM_NC,.quadwp_io_num = GPIO_NUM_NC,.quadhd_io_num = GPIO_NUM_NC,.max_transfer_sz = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_DRAW_BUFF_HEIGHT * sizeof(uint16_t),};ESP_RETURN_ON_ERROR(spi_bus_initialize(EXAMPLE_LCD_SPI_NUM, &buscfg, SPI_DMA_CH_AUTO), TAG, "SPI init failed");ESP_LOGD(TAG, "Install panel IO");const esp_lcd_panel_io_spi_config_t io_config = {.dc_gpio_num = EXAMPLE_LCD_GPIO_DC,.cs_gpio_num = EXAMPLE_LCD_GPIO_CS,.pclk_hz = EXAMPLE_LCD_PIXEL_CLK_HZ,.lcd_cmd_bits = EXAMPLE_LCD_CMD_BITS,.lcd_param_bits = EXAMPLE_LCD_PARAM_BITS,.spi_mode = 0,.trans_queue_depth = 10,};ESP_GOTO_ON_ERROR(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)EXAMPLE_LCD_SPI_NUM, &io_config, &lcd_io), err, TAG, "New panel IO failed");ESP_LOGD(TAG, "Install LCD driver");const esp_lcd_panel_dev_config_t panel_config = {.reset_gpio_num = EXAMPLE_LCD_GPIO_RST,.color_space = EXAMPLE_LCD_COLOR_SPACE,.bits_per_pixel = EXAMPLE_LCD_BITS_PER_PIXEL,};ESP_GOTO_ON_ERROR(esp_lcd_new_panel_st7789(lcd_io, &panel_config, &lcd_panel), err, TAG, "New panel failed");esp_lcd_panel_reset(lcd_panel);esp_lcd_panel_init(lcd_panel);esp_lcd_panel_mirror(lcd_panel, true, true);esp_lcd_panel_disp_on_off(lcd_panel, true);/* LCD backlight on */ESP_ERROR_CHECK(gpio_set_level(EXAMPLE_LCD_GPIO_BL, EXAMPLE_LCD_BL_ON_LEVEL));return ret;err:if (lcd_panel) {esp_lcd_panel_del(lcd_panel);}if (lcd_io) {esp_lcd_panel_io_del(lcd_io);}spi_bus_free(EXAMPLE_LCD_SPI_NUM);return ret;
}static esp_err_t app_lvgl_init(void)
{/* Initialize LVGL */const lvgl_port_cfg_t lvgl_cfg = {.task_priority = 4,         /* LVGL task priority */.task_stack = 4096,         /* LVGL task stack size */.task_affinity = -1,        /* LVGL task pinned to core (-1 is no affinity) */.task_max_sleep_ms = 500,   /* Maximum sleep in LVGL task */.timer_period_ms = 5        /* LVGL timer tick period in ms */};ESP_RETURN_ON_ERROR(lvgl_port_init(&lvgl_cfg), TAG, "LVGL port initialization failed");/* Add LCD screen */ESP_LOGD(TAG, "Add LCD screen");const lvgl_port_display_cfg_t disp_cfg = {.io_handle = lcd_io,.panel_handle = lcd_panel,.buffer_size = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_DRAW_BUFF_HEIGHT * sizeof(uint16_t),.double_buffer = EXAMPLE_LCD_DRAW_BUFF_DOUBLE,.hres = EXAMPLE_LCD_H_RES,.vres = EXAMPLE_LCD_V_RES,.monochrome = false,/* Rotation values must be same as used in esp_lcd for initial settings of the screen */.rotation = {.swap_xy = false,.mirror_x = true,.mirror_y = true,},.flags = {.buff_dma = true,.swap_bytes = true,}};lvgl_disp = lvgl_port_add_disp(&disp_cfg);return ESP_OK;
}static void _app_button_cb(lv_event_t *e)
{lv_disp_rotation_t rotation = lv_disp_get_rotation(lvgl_disp);rotation++;if (rotation > LV_DISPLAY_ROTATION_270) {rotation = LV_DISPLAY_ROTATION_0;}/* LCD HW rotation */lv_disp_set_rotation(lvgl_disp, rotation);
}static void app_main_display(void)
{lv_obj_t *scr = lv_scr_act();/* Task lock */lvgl_port_lock(0);/* Your LVGL objects code here .... *//* Label */lv_obj_t *label = lv_label_create(scr);lv_obj_set_width(label, EXAMPLE_LCD_H_RES);lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0);
#if LVGL_VERSION_MAJOR == 8lv_label_set_recolor(label, true);lv_label_set_text(label, "#FF0000 "LV_SYMBOL_BELL" Hello world Espressif and LVGL "LV_SYMBOL_BELL"#\n#FF9400 "LV_SYMBOL_WARNING" For simplier initialization, use BSP "LV_SYMBOL_WARNING" #");
#elselv_label_set_text(label, LV_SYMBOL_BELL" Hello world Espressif and LVGL "LV_SYMBOL_BELL"\n "LV_SYMBOL_WARNING" For simplier initialization, use BSP "LV_SYMBOL_WARNING);
#endiflv_obj_align(label, LV_ALIGN_CENTER, 0, -30);/* Button */lv_obj_t *btn = lv_btn_create(scr);label = lv_label_create(btn);lv_label_set_text_static(label, "Rotate screen");lv_obj_align(btn, LV_ALIGN_BOTTOM_MID, 0, -30);lv_obj_add_event_cb(btn, _app_button_cb, LV_EVENT_CLICKED, NULL);/* Task unlock */lvgl_port_unlock();
}void app_main(void)
{/* LCD HW initialization */ESP_ERROR_CHECK(app_lcd_init());/* LVGL initialization */ESP_ERROR_CHECK(app_lvgl_init());/* Show LVGL objects */app_main_display();
}

5 发现问题

  • 发现是花屏,需要进入开启 Swap the 2 bytes of RGB565 color. Useful if the display has an 8-bit interface (e.g. SPI).

    在这里插入图片描述

  • 发现 颜色是反的, app_lcd_init 添加代码

    esp_lcd_panel_invert_color(lcd_panel, true);
    
  • 发现显示屏错位了,Y坐标 起点是 -80 并不是0,app_lcd_init 添加代码

     esp_lcd_panel_set_gap(lcd_panel, 0, 80);
    

文章是自己总结而记录,有些知识点没说明白的,请各位看官多多提意见,多多交流,欢迎大家留言
如果技术交流可以加以下群,方便沟通
QQ群:370278903
点击链接加入群聊【蜡笔小芯的嵌入式交流群】
![])

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

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

相关文章

【Vue】前端Crypto-js加密库md5加密转成二进制/十六进制/Base64格式

MD5是一种常用的哈希函数&#xff0c;用于生成数据的消息摘要&#xff0c;在前端开发中&#xff0c;我们经常需要对数据进行加密&#xff0c;以确保数据的安全性。 Crypto-js是一个常用的JavaScript加密库&#xff0c;它提供了MD5算法的实现&#xff0c;并且支持将加密结果转换…

C++_ 头指针在链表的操作中用来标识链表的起始位置

链表&#xff08;linked list&#xff09;是一种常见的数据结构&#xff0c;用于存储一系列元素。它由一系列节点组成&#xff0c;每个节点包含数据和指向下一个节点的指针。 在 C 中&#xff0c;可以使用结构体来表示链表节点&#xff0c;然后使用指针将这些节点连接起来。 -…

kafka学习记录

文章目录 windows单机版kafka搭建步骤主题的增删改查操作消息的生产与消费 Windows集群版kafka搭建步骤 prettyZoo 尚硅谷Kafka教程&#xff0c;2024新版kafka视频&#xff0c;零基础入门到实战 【尚硅谷】Kafka3.x教程&#xff08;从入门到调优&#xff0c;深入全面&#xff0…

分库分表-简单了解

通过下面这些文章&#xff0c;我知道了什么是分库分表&#xff0c; 以及 什么时候需要分库分表&#xff0c; 还有分库分表带来的问题。 我说MySQL单表超过2000w就要分库分表&#xff0c;面试官让我回去等通知&#xff1f; 目前还没有学习到分布式&#xff0c;微服务&#xf…

plsql developer 一键格式化sql/美化sql

PL/SQL 格式化工具 以 Oracle SQL Developer 为例&#xff0c;使用一键格式化的步骤如下&#xff1a; 打开 Oracle SQL Developer。在“文件”菜单中&#xff0c;选择“打开文件”&#xff0c;然后选择你的 PL/SQL 文件。打开文件后&#xff0c;你可以通过右键菜单选择“格式…

vue3 知识点的补充 之 第一节

01 vue2与vue3的区别 vue2 采用object.defuneProperty()实现 对数组不友好 重写了数组的方法&#xff0c;同时无法监听数组length长度的改变。对于对象只能劫持设置好的数据 新增需要使用vue.set vue3 采用proxy进行代理&#xff0c;不需要重写数组的方法 同时可以监听数组长度…

gdb相关指令

背景知识 通过上图&#xff0c;可以看到&#xff0c;gcc 和 g 默认形成的可执行程序是release的&#xff01;&#xff01;&#xff01;故无法直接被调试。因此带 -g 选项表示使用 Debug 模式进行编译&#xff0c;而且我们可以看到&#xff0c;Debug 模式下编译形成的可执…

OSCP靶场--ClamAV

OSCP靶场–ClamAV 考点 1.nmap扫描 ##┌──(root㉿kali)-[~/Desktop] └─# nmap -sV -sC 192.168.153.42 -p- -Pn --min-rate 2500 Starting Nmap 7.92 ( https://nmap.org ) at 2024-04-13 10:01 EDT Nmap scan report for 192.168.153.42 Host is up (0.24s latency). N…

ssl认证 生成证书的代码 java

网上流行的 InstallCert.java&#xff0c;应该出自于官网。但现在也找不到了&#xff0c;只能找到2011年的一篇文章&#xff08;在文章底下的参考链接&#xff09;。 以下是生成证书的代码&#xff1a; import java.io.BufferedReader; import java.io.File; import java.io.…

题目一 搭建电商平台WordPress

创建VPC01和VPC02&#xff0c;两个安全组&#xff08;按考试时拓扑图中实际要求的名称来创建&#xff0c;可能VPC 的名称是&#xff1a;web-active, db&#xff0c;上海容灾的VPC名称是&#xff1a; web-dril1&#xff09;&#xff0c;安全组要求最小化放行&#xff0c;包括业务…

033. 字母异位词分组

给定一个字符串数组 strs &#xff0c;将 变位词 组合在一起。 可以按任意顺序返回结果列表。 注意&#xff1a;若两个字符串中每个字符出现的次数都相同&#xff0c;则称它们互为变位词。 示例 1: 输入: strs [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”] 输出…

Ubuntu去除烦人的顶部【活动】按钮

文章目录 一、需求说明二、打开 extensions 网站三、安装 GNOME Shell 插件四、安装本地连接器五、安装 Hide Activities Button 插件六、最终效果七、卸载本地连接器命令参考 本文所使用的 Ubuntu 系统版本是 Ubuntu 22.04 ! 一、需求说明 使用 Ubuntu 的过程中&#xff0c;屏…

VNC Viewer 连接远程主机及常见错误处理(The connection closed unexpectedly)

搭建可接收vnc连接的环境 1、下载镜像 https://github.com/fcwu/docker-ubuntu-vnc-desktop 该镜像是含有ubuntu 通过docker运行的桌面环境&#xff0c;并接受vnc 的连接 docker pull dorowu/ubuntu-desktop-lxde-vnc 2、运行容器 1&#xff09;只暴露容器的80端口&#…

二叉树练习day.9

669.修剪二叉搜索树 链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; 给你二叉搜索树的根节点 root &#xff0c;同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树&#xff0c;使得所有节点的值在[low, high]中。修剪树 不应该 改变…

多模态 Multi-Module的创新点

最近在改论文 用了多模态 记得最早找创新点时 记录了关于多模态相关的一些值得深入研究的方向 记录于此 希望分享交流 *注:多模态不止多信息源; 除了不同的感知模态(如视觉、听觉、触觉等)之外,多模态还可以涉及到不同的数据表示、不同的特征空间、不同的数据类型等…

【从零单排Golang】第十六话:channel的用法和基本原则

在基于Golang的后端开发中&#xff0c;channel是一个必须要掌握的并发编程概念。和python的queue一样&#xff0c;channel在不同的goroutine里承担着传递信息的作用&#xff0c;使得业务逻辑的状态上下文可以在不同的goroutine中共享。今天&#xff0c;我们就来看一下channel的…

C语言隐藏执行其他程序

WinExec函数 #include<windows.h> int main() {WinExec("notepad.exe", SW_HIDE);return 0; }SW_HIDE 隐藏SW_SHOW 显示 ShellExecute函数 在C语言中使用ShellExecute函数可以执行外部程序&#xff0c;比如打开一个文件、运行一个程序等。 #include <wi…

Singleton单例设计模式详解

目录 模式定义应用场景实现方式1.懒汉模式&#xff1a;2.饿汉模式&#xff1a;3.静态内部类反射如何防止反射攻击破坏&#xff1f; 枚举类型序列化 部分源码中的应用定位Spring & JDKTomcat反序列化指定数据源 模式定义 保证一个类只有一个实例&#xff0c;并且提供一个全…

pytorch车牌识别

目录 使用pytorch库中CNN模型进行图像识别收集数据集定义CNN模型卷积层池化层全连接层 CNN模型代码使用模型 使用pytorch库中CNN模型进行图像识别 收集数据集 可以去找开源的数据集或者自己手做一个 最终整合成 类别分类的图片文件 定义CNN模型 卷积层 功能&#xff1a;提…

Chatgpt掘金之旅—有爱AI商业实战篇|播客剧本写作|(十三)

演示站点&#xff1a; https://ai.uaai.cn 对话模块 官方论坛&#xff1a; www.jingyuai.com 京娱AI 一、AI技术创业播客剧本写作服务有哪些机会&#xff1f; 人工智能&#xff08;AI&#xff09;技术作为当今科技创新的前沿领域&#xff0c;为创业者提供了广阔的机会和挑战。…