ESP32S3 使用LVGL驱动LCD屏(ST7789主控)

ESP32S3 使用LVGL驱动LCD屏(ST7789主控)


目录

1 分析原理图
2 驱动、点亮LCD(ST7789)
  2.1 在工程中添加目录、文件
  2.2 添加esp_lvgl_port组件
  2.3 对工程进行必要的配置
  2.4 编写必要代码
3 烧录、验证


1 分析原理图

要使用SOC驱动LCD屏,首先需要看的就是硬件原理图,主要要看的是用的什么驱动芯片、驱动接口类型、具体的引脚连接等。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

    通过这部分原理图,可以知道,主控用的是8MB Flash的ESP32S3-WROOM模组,LCD驱动芯片为ST7789,驱动接口为SPI接口。IO9控制的是LCD的亮度、IO10为ST7789的SPI片选、IO12为ST7789的SPI时钟、IO11和IO13则为ST7789的SPI数据输入输出,其他的还有一些复位信号、背光信号。


2 驱动、点亮LCD(ST7789)

我们在博文

IDF项目添加LVGL组件 创建的工程的基础上,进一步实现LCD屏幕的驱动点亮。

2.1 在工程中添加目录、文件

在工程中的main路径下创建一个文件夹lvgl_options,并在其中创建文件lvgl_options.h、lvgl_options.c。

在这里插入图片描述

    修改main路径下的CMakeLists.txt文件,将lvgl_options路径下的文件添加进构建系统。

在这里插入图片描述

2.2 添加esp_lvgl_port组件

在ESP组件中心搜索esp_lvgl_port组件,并通过idf 命令将其添加进工程。
idf.py clean
idf.py add-dependency "espressif/esp_lvgl_port^2.4.3"
idf.py set-target esp32s3

在这里插入图片描述

在这里插入图片描述

2.3 对工程进行必要的配置

根据模组的实际flash情况配置flash。

在这里插入图片描述

    根据模组的实际ram情况配置ram。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

    根据LCD情况和实际内存资源情况,调整LVGL相关配置。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.4 编写必要代码

首先需要初始化对应的SPI 总线,通过创建一个spi_bus_config_t类型的对象,调用接口 spi_bus_initialize() 可以完成 SPI 总线的初始化。
spi_bus_config_t buscfg = {.sclk_io_num = EXAMPLE_LCD_GPIO_SCLK,.mosi_io_num = EXAMPLE_LCD_GPIO_MOSI,.miso_io_num = EXAMPLE_LCD_GPIO_MISO,.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");

    在完成了SPI 总线的初始化后,就可以开始初始化LCD设备了,LCD设备的初始化需要先创建一个esp_lcd_panel_io_spi_config_t类型的对象完成实际SPI的配置,再通过esp_lcd_new_panel_io_spi()接口完成lcd_io对象的创建,再通过lcd_io对象完成lcd_panel的创建。

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_CLOCK_SPEED_HZ,.lcd_cmd_bits = EXAMPLE_LCD_CMD_BITS,.lcd_param_bits = EXAMPLE_LCD_PARAM_BITS,.spi_mode = EXAMPLE_LCD_SPI_MODE,.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");const esp_lcd_panel_dev_config_t panel_config = {//.reset_gpio_num = EXAMPLE_LCD_GPIO_RST,.reset_gpio_num = GPIO_NUM_NC,.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");

    在完成了SPI和LCD设备的初始化后,就可以初始化lvgl组件了。主要就是调用lvgl_port_init()和lvgl_port_add_disp()。

    完整的lvgl_options.h

#ifndef _MY_LVGL_OPTIONS_H_
#define _MY_LVGL_OPTIONS_H_#ifdef __cplusplus
extern "C" {
#endifvoid lvgl_options_test(void);#ifdef __cplusplus
} /* extern "C" */
#endif#endif 

    完整的lvgl_options.c

#include "esp_err.h"
#include "esp_log.h"
#include "esp_check.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"#include "lvgl_options.h"// ST7789 参数
#define SPI_TFT_ST7789_CLOCK_SPEED_HZ      (60*1000*1000) 
#define SPI_TFT_ST7789_SPI_MODE            (2)/* LCD size */
#define EXAMPLE_LCD_H_RES   (240)
#define EXAMPLE_LCD_V_RES   (320)/* LCD settings */
#define EXAMPLE_LCD_SPI_NUM         (SPI3_HOST)
#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 (320)
#define EXAMPLE_LCD_BL_ON_LEVEL      (1)#define EXAMPLE_LCD_SPI_MODE        SPI_TFT_ST7789_SPI_MODE
#define EXAMPLE_LCD_CLOCK_SPEED_HZ  SPI_TFT_ST7789_CLOCK_SPEED_HZ
#define EXAMPLE_LCD_GPIO_SCLK       (GPIO_NUM_12)
#define EXAMPLE_LCD_GPIO_MOSI       (GPIO_NUM_11)
#define EXAMPLE_LCD_GPIO_MISO       (GPIO_NUM_13)
//#define EXAMPLE_LCD_GPIO_RST        (GPIO_NUM_48)
#define EXAMPLE_LCD_GPIO_DC         (GPIO_NUM_9)
#define EXAMPLE_LCD_GPIO_CS         (GPIO_NUM_10)
//#define EXAMPLE_LCD_GPIO_BL         (GPIO_NUM_45)static const char *TAG = "lvgl_options";// LVGL image declare
LV_IMG_DECLARE(esp_logo)/* 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 spi_bus_init(void)
{esp_err_t ret = ESP_OK;spi_bus_config_t buscfg = {.sclk_io_num = EXAMPLE_LCD_GPIO_SCLK,.mosi_io_num = EXAMPLE_LCD_GPIO_MOSI,.miso_io_num = EXAMPLE_LCD_GPIO_MISO,.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),};// 初始化SPI 总线ESP_LOGD(TAG, "Initialize SPI bus");ESP_RETURN_ON_ERROR(spi_bus_initialize(EXAMPLE_LCD_SPI_NUM, &buscfg, SPI_DMA_CH_AUTO), TAG, "SPI init failed");return ret;
}static esp_err_t app_lcd_init(void)
{esp_err_t ret = ESP_OK;ESP_LOGD(TAG, "Install LCD driver");// 初始化 LCD SPIESP_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_CLOCK_SPEED_HZ,.lcd_cmd_bits = EXAMPLE_LCD_CMD_BITS,.lcd_param_bits = EXAMPLE_LCD_PARAM_BITS,.spi_mode = EXAMPLE_LCD_SPI_MODE,.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");const esp_lcd_panel_dev_config_t panel_config = {//.reset_gpio_num = EXAMPLE_LCD_GPIO_RST,.reset_gpio_num = GPIO_NUM_NC,.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 = 6144,         /* 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,.trans_size = EXAMPLE_LCD_H_RES * (EXAMPLE_LCD_DRAW_BUFF_HEIGHT / 2),.double_buffer = EXAMPLE_LCD_DRAW_BUFF_DOUBLE,.hres = EXAMPLE_LCD_H_RES,.vres = EXAMPLE_LCD_V_RES,.monochrome = false,
#if LVGL_VERSION_MAJOR >= 9.color_format = LV_COLOR_FORMAT_RGB565,
#endif.rotation = {.swap_xy = false,.mirror_x = false,.mirror_y = true,},.flags = {//.buff_dma = true,.buff_spiram = true,
#if LVGL_VERSION_MAJOR >= 9//.swap_bytes = true,
#endif  }};lvgl_disp = lvgl_port_add_disp(&disp_cfg);return ESP_OK;
}static void app_main_display(void)
{lv_obj_t *scr = lv_scr_act();/* Task lock */lvgl_port_lock(0);/* 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, 20);/* Task unlock */lvgl_port_unlock();
}void lvgl_options_test(void)
{ESP_LOGD(TAG, "lvgl_options_test");/* SPI BUS  initialization*/ESP_ERROR_CHECK(spi_bus_init());/* LCD HW initialization */ESP_ERROR_CHECK(app_lcd_init());/* LVGL initialization */ESP_ERROR_CHECK(app_lvgl_init());/* Show LVGL objects */app_main_display();return;
}

3 烧录、验证

经过上述的添加依赖组件、设定工程配置、编写必要代码后,就可以编译、烧录进设备进行验证了。测试结果显然是符合预期的。

在这里插入图片描述

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

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

相关文章

Sigrity Optimize PI CapGen仿真教程文件路径

为了方便读者能够快速上手和学会Sigrity Optimize PI和 Deacap Generate 的功能,将Sigrity Optimize PI CapGen仿真教程专栏所有文章对应的实例文件上传至以下路径 https://download.csdn.net/download/weixin_54787054/90171471?spm1001.2014.3001.5503

2024年“羊城杯”粤港澳大湾区网络安全大赛 初赛 Web数据安全AI 题解WriteUp

文章首发于【先知社区】:https://xz.aliyun.com/t/15442 Lyrics For You 题目描述:I have wrote some lyrics for you… 开题。 看一下前端源码,猜测有路径穿越漏洞 http://139.155.126.78:35502/lyrics?lyrics../../../../../etc/passw…

NLP 中文拼写检测开源-03-hunspell 拼写纠正算法入门介绍 CSC

拼写纠正系列 NLP 中文拼写检测实现思路 NLP 中文拼写检测纠正算法整理 NLP 英文拼写算法,如果提升 100W 倍的性能? NLP 中文拼写检测纠正 Paper java 实现中英文拼写检查和错误纠正?可我只会写 CRUD 啊! 一个提升英文单词拼…

SpringCloud 运用(3)—— Nacos配置中心

上一篇:SpringCloud 入门(2)—— 跨服务调度-CSDN博客 Nacos是阿里巴巴开源的服务发现与配置管理基础设施,旨在帮助开发者更轻松地构建云原生应用。它提供了一组简单易用的特性集,支持动态服务发现、配置管理和服务管理…

门户系统需要压测吗?以及门户系统如何压力测试?

一、门户系统为什么要进行压力测试? 首先一点要明确一下,统一门户上线以后,将是所有应用系统的入口,对应门户稳定性要求较高,门户实现了统一入口和统一认证,系统宕机将影响其他系统使用。一般部署架构要求…

专题八:背包问题

> 作者:დ旧言~ > 座右铭:松树千年终是朽,槿花一日自为荣。 > 目标:了解什么是记忆化搜索,并且掌握记忆化搜索算法。 > 毒鸡汤:有些事情,总是不明白,所以我不会坚持。早…

SpringBoot核心:自动配置

有使用过SSM框架的,还记得曾经在spring-mybatis.xml配置了多少内容吗?数据源、连接池、会话工厂、事务管理,而现在Spring Boot告诉你这些都不需要了,简单的几个注解统统搞定,是不是很方便! 前言 SpringBoo…

python 定时任务管理封装

主逻辑代码 # -*- coding: utf-8 -*- # import apscheduler import pandas as pd from datetime import datetime # 导入调度器,此处使用BackgroundScheduler阻塞调度器 from apscheduler.schedulers.background import BackgroundScheduler # 导入触发器&#xf…

APP投放的归因框架设计

一、归因相关概念回顾 在广告归因简介中我们介绍常见的归因模型和归因方法,我们先来回顾一下: 1. 背景 2. 设备标识 3. 归因模型 归因模型的多样性意味着每种模型都有其独特的优势和局限。关键在于选择一个与您的业务场景相匹配的模型,并且…

Kunlun 2280服务器(ARM)Raid卡磁盘盘符漂移问题解决

一、问题描述 1、服务器:Kunlun 2280服务器 ARM 2、操作系统:Euler2.0Sp10 Arm 3、Raid卡型号:MeGaRAID 9560-8i 4、Raid配置:2块配置Raid1作为系统盘,剩余磁盘配置Raid5 作为数据盘 二、问题现象 1、使用IBMC页面配置Raid卡,1个Raid1 系统盘和1个Raid5数…

[搜广推]王树森推荐系统——Deep Retrieval 召回

Deep Retrieval 简介 Deep Retrieval 是一种推荐系统框架,它将物品表示为路径(path),并在线上查找与用户最匹配的路径。 这种方法与传统的双塔模型不同,后者通常将用户和物品表示为向量,并在线上进行最近邻…

RabbitMQ 的7种工作模式

RabbitMQ 共提供了7种⼯作模式,进⾏消息传递,. 官⽅⽂档:RabbitMQ Tutorials | RabbitMQ 1.Simple(简单模式) P:⽣产者,也就是要发送消息的程序 C:消费者,消息的接收者 Queue:消息队列,图中⻩⾊背景部分.类似⼀个邮箱,可以缓存消息;⽣产者向其中投递消息,消费者从其中取出消息…

PCIe_Host驱动分析_设备枚举

往期内容 本文章相关专栏往期内容,PCI/PCIe子系统专栏: 嵌入式系统的内存访问和总线通信机制解析、PCI/PCIe引入 深入解析非桥PCI设备的访问和配置方法 PCI桥设备的访问方法、软件角度讲解PCIe设备的硬件结构 深入解析PCIe设备事务层与配置过程 PCIe的三…

深入浅出:多功能 Copilot 智能助手如何借助 LLM 实现精准意图识别

阅读原文 1. Copilot中的意图识别 如果要搭建一个 Copilot 智能助手,比如支持 知识问答、数据分析、智能托管、AIGC 等众多场景或能力,那么最核心的就是基于LLM进行意图识别分发能力,意图识别的准确率直接决定了 Copilot 智能助手的能力上限…

Jo-im开发:用于WebRTC的ICE中继服务器Coturn搭建

前言 本人计划开发一套具备文本、语音、视频通话功能的IM demo,同时具备多人在线会议功能,按习惯大概会开源版定义名称为Duihao jo-im,本案主要用于实现语音视频通话的基础组件支撑。因为我们选择基于WebRTC实现IM中语音、视频通话&#xff…

【CVE-2024-53375】TP-Link Archer系列路由器认证操作系统命令注入(内附远离和代码利用)

CVE-2024-53375 TP-Link Archer系列路由器认证操作系统命令注入 受影响的设备 使用 HomeShield 功能的 TP-Link 设备容易受到此漏洞的影响。这包括 TP-Link Archer 系列的多款路由器。 经过测试 Archer AXE75(EU)_V1_1.2.2 Build 20240827(发布日期 2024 年 11 月 4 日)…

程控电阻箱应用中需要注意哪些安全事项?

程控电阻箱是一种用于精确控制电路中电流和电压的电子元件,广泛应用于电子实验、测试设备以及精密测量仪器中。在应用程控电阻箱时,为确保安全和设备的正常运行,需要注意以下几个安全事项: 1. 正确连接:确保电阻箱与电…

Promise链式调用

Promise链式调用 上一篇我们实现了通过promise的方式实现获取国家基本信息,本次我们来使用promise链式调用来实现邻国的展现 首先,我们从第一个国家中获取到邻国的国家代码名称 const neighbour data[0].borders[0];然后我们通过fetch来获取邻国信息&a…

Elasticsearch相关知识@1

目录标题 Lucene1. **什么是 Lucene?**2. **Lucene 在 Elasticsearch 中的作用**3. **Lucene 的核心功能**(1) **倒排索引**(2) **分词**(3) **查询解析**(4) **相关性评分** 4. **为什么 Elasticsearch 使用 Lucene?**5. **Lucene 和 Elasticsearch 的区别**6. **总结** 分片…

UE5 渲染管线 学习笔记

兰伯特 SSS为散射的意思 带Bias的可以根据距离自动切换mip的卷积值 而带Level的值mipmaps的定值 #define A8_SAMPLE_MASK .a 这样应该就很好理解了 这个只采样a通道 带Level的参考上面的 朝左上和右下进行模糊 带Bias参考上面