当前位置: 首页 > news >正文

1. 基于ESP32-S3的1.9寸ST7789V3彩屏SPI驱动移植与实战

基于ESP32-S3的1.9寸ST7789V3彩屏SPI驱动移植与实战

最近在ESP32-S3上折腾一个小屏幕,发现这块1.9寸的ST7789V3彩屏性价比挺高,显示效果也不错,但网上的驱动资料比较零散。我花了不少时间把软件SPI和硬件SPI两种驱动方式都调通了,今天就把完整的移植过程分享出来,手把手教你怎么让这块屏幕在ESP32-S3上亮起来。

这篇教程适合正在用ESP32-S3做显示项目的朋友,无论你是刚入门还是有一定经验的开发者,都能跟着步骤完成。咱们会从硬件接线开始,讲到驱动代码的获取和集成,最后用实际代码验证显示效果。过程中我会分享一些调试时踩过的坑,帮你少走弯路。

1. 屏幕与硬件准备

1.1 屏幕规格与资料获取

咱们用的这块是1.9寸的彩色LCD屏幕,驱动芯片是ST7789V3。先来看看它的基本参数:

参数规格
工作电压3.3V
工作电流约50mA
模块尺寸29mm (高) x 62mm (宽)
显示分辨率170 (水平) x 320 (垂直) RGB
通信协议SPI (支持软件SPI和硬件SPI)
引脚数量8 Pin (2.54mm间距排针)

屏幕的采购链接和资料包我都放在这里,方便你获取:

  • 采购链接:淘宝商品链接
  • 资料下载:链接: https://pan.baidu.com/s/1ArmQST7I84UYY7n0aJdEBw 提取码: 8888

资料包里包含了完整的驱动代码、示例程序和一些文档,是咱们后续移植的基础。

1.2 通信原理:SPI简介

这块屏幕通过SPI接口和ESP32-S3通信。SPI是一种高速、全双工的同步通信协议,简单理解就是主设备(MCU)和从设备(屏幕)之间用几根线来“对话”。

  • SCK (SCL):时钟线,由主设备产生,像打拍子一样同步数据收发。
  • MOSI (SDA):主设备输出、从设备输入线,主设备通过这根线发送数据给屏幕。
  • CS:片选线,当主设备要和某个从设备通信时,就把对应从设备的这根线拉低(选中它)。
  • 其他引脚:除了上述SPI必需的引脚,屏幕还有DC(数据/命令选择)、RES(复位)、BLK(背光控制)等控制引脚。

ESP32-S3芯片内部集成了多个SPI控制器:

  • SPI0 & SPI1:主要预留给内部访问外部Flash和PSRAM,我们一般不用。
  • SPI2 (GP-SPI2) & SPI3 (GP-SPI3):这两个是通用的SPI控制器,我们可以自由使用,也就是常说的“硬件SPI”。

“软件SPI”则是用普通的GPIO引脚,通过程序模拟SPI的时序来通信,好处是引脚选择灵活,但速度比硬件SPI慢。

2. 硬件连接:引脚接线图

接线是第一步,也是最容易出错的一步。屏幕有8个引脚,我们需要根据选择的通信方式(软件SPI或硬件SPI)连接到ESP32-S3对应的GPIO上。

2.1 软件SPI接线

软件SPI不挑剔引脚,你可以选择ESP32-S3上任意空闲的GPIO。下面是我推荐的一组引脚连接,比较常用:

表2.1-1 1.9寸屏引脚说明

屏幕引脚标号引脚名称功能说明
1GND电源地
2VCC电源正 (3.3V)
3SCLSPI时钟线 (SCK)
4SDASPI数据线 (MOSI)
5RES复位引脚 (低电平有效)
6DC数据/命令选择引脚
7CS片选引脚 (低电平有效)
8BLK背光控制 (高电平点亮)

表2.1-2 软件SPI推荐接线方式

ESP32-S3 GPIO连接至屏幕引脚备注
GPIO2SCL (3)SPI时钟
GPIO3SDA (4)SPI数据输出
GPIO4RES (5)复位信号
GPIO5DC (6)数据/命令选择
GPIO6CS (7)片选信号
GPIO7BLK (8)背光控制
3.3VVCC (2)电源
GNDGND (1)电源地

注意:如果你的项目GPIO紧张,有两个引脚可以简化:

  1. RES引脚:可以接到ESP32-S3的复位引脚(EN)。这样开发板复位时,屏幕也跟着复位,省下一个GPIO。代价是无法通过软件单独复位屏幕。
  2. BLK引脚:可以直接接到3.3V或悬空。接到3.3V则背光常亮,悬空则背光不亮(通常内部有弱上拉,可能微亮)。代价是失去了通过程序调节背光亮度的能力。

2.2 硬件SPI接线

硬件SPI需要连接到ESP32-S3指定的SPI功能引脚上,这样才能发挥硬件加速的优势。这里我们以使用SPI2_HOST(即GP-SPI2)为例。

表2.2-1 硬件SPI推荐接线方式 (使用SPI2)

ESP32-S3 GPIO默认SPI2功能连接至屏幕引脚
GPIO12SPI2_CLKSCL (3)
GPIO11SPI2_MOSISDA (4)
GPIO4(自定义GPIO)RES (5)
GPIO5(自定义GPIO)DC (6)
GPIO6(自定义GPIO)CS (7)
GPIO7(自定义GPIO)BLK (8)

可以看到,对于硬件SPI,只有时钟(SCK)和数据输出(MOSI)必须使用固定的功能引脚(GPIO12和GPIO11)。RESDCCSBLK这些控制引脚依然可以像软件SPI一样自由分配普通GPIO。

3. 驱动移植:将代码集成到你的工程

硬件接好线,接下来就是把驱动代码“搬”到我们的ESP32-S3项目里。资料包里已经提供了写好的驱动,我们只需要把它放到正确的位置并修改配置文件。

3.1 获取驱动文件

首先,你需要从之前提供的资料下载链接中,找到驱动文件包。根据原文指引,文件位于:资料下载中心 -> 模块移植资料下载 -> 该章节配套压缩包中。

下载后解压,你会找到一个名为LCD的文件夹。这个文件夹里就包含了驱动屏幕所需的所有源文件(.c.h)。

3.2 将驱动文件加入工程

  1. 复制文件:打开你的ESP-IDF项目,将下载得到的整个LCD文件夹,复制到你项目的main目录下。通常你的项目结构会像这样:

    你的项目/ ├── CMakeLists.txt ├── main/ │ ├── CMakeLists.txt │ ├── main.c │ └── LCD/ <-- 把文件夹复制到这里 │ ├── lcd_init.c │ ├── lcd_init.h │ ├── lcd.c │ └── ...
  2. 修改编译配置:为了让编译器知道这些新文件的存在,需要修改main目录下的CMakeLists.txt文件。 用VS Code或其他编辑器打开main/CMakeLists.txt,在idf_component_register部分添加LCD文件夹的路径。通常是在SRCSINCLUDE_DIRS里添加。

    一个简单的修改示例如下:

    idf_component_register(SRCS "main.c" "LCD/lcd_init.c" "LCD/lcd.c" # ... 添加其他LCD文件夹下的.c文件 INCLUDE_DIRS "." "LCD" # 添加这一行,让编译器能找到.h文件 )

    更规范的做法是使用aux_source_directory命令自动添加所有.c文件,但手动列出更清晰,也不容易出错。

3.3 关键配置:根据接线修改引脚定义

驱动文件里有一个关键的头文件(通常是lcd_init.hlcd_conf.h),里面定义了所有用到的GPIO引脚编号。你必须根据你实际的接线方式修改这里!

打开LCD/lcd_init.h文件,找到类似下面的引脚定义部分:

// 软件SPI引脚定义示例 #define LCD_SCL_PIN 2 #define LCD_SDA_PIN 3 #define LCD_RES_PIN 4 #define LCD_DC_PIN 5 #define LCD_CS_PIN 6 #define LCD_BLK_PIN 7 // 或者硬件SPI引脚定义示例 #define LCD_SPI_HOST SPI2_HOST #define LCD_SCLK_PIN 12 #define LCD_MOSI_PIN 11 #define LCD_RES_PIN 4 #define LCD_DC_PIN 5 #define LCD_CS_PIN 6 #define LCD_BLK_PIN 7

请务必将这些#define后面的数字,改成你实际连接ESP32-S3的GPIO编号。如果你用的是硬件SPI,还需要确认LCD_SPI_HOST与你使用的SPI控制器一致(SPI2_HOSTSPI3_HOST)。

修改完引脚定义,驱动移植的核心工作就完成了。

4. 功能验证:编写测试程序点亮屏幕

代码集成好了,引脚也配置对了,是时候上电测试了。我们在主程序main.c里写一段简单的测试代码,来验证屏幕是否正常工作。

4.1 测试代码解析

打开你的main/main.c文件,将内容替换为以下测试代码。这段代码会初始化屏幕,先清屏为白色,然后循环显示一些文字、数字、图片和一个递增的浮点数。

#include <stdio.h> #include <inttypes.h> #include "sdkconfig.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_chip_info.h" #include "esp_flash.h" #include "esp_timer.h" // 包含我们移植的LCD驱动头文件 #include "LCD/lcd_init.h" #include "LCD/lcd.h" #include "LCD/pic.h" // 包含图片数据 void app_main(void) { float t = 0.0; // 用于演示的浮点数变量 LCD_Init(); // 第一步:初始化LCD屏幕,这是必须的! LCD_Fill(0, 0, LCD_W, LCD_H, WHITE); // 第二步:用白色填充整个屏幕 while(1) { // 以下代码在循环中执行,动态刷新显示内容 // 1. 显示中文 LCD_ShowChinese(40, 0, (uint8_t *)"中电科", RED, WHITE, 32, 0); // 2. 显示字符串和屏幕宽度 LCD_ShowString(10, 33, (uint8_t *)"LCD_W:", RED, WHITE, 32, 0); LCD_ShowIntNum(106, 33, LCD_W, 3, RED, WHITE, 32); // LCD_W是驱动里定义的屏幕宽度 // 3. 显示字符串和屏幕高度 LCD_ShowString(10, 66, (uint8_t *)"LCD_H:", RED, WHITE, 32, 0); LCD_ShowIntNum(106, 66, LCD_H, 3, RED, WHITE, 32); // LCD_H是驱动里定义的屏幕高度 // 4. 显示一个不断增加的浮点数 LCD_ShowFloatNum1(10, 99, t, 4, RED, WHITE, 32); t += 0.11; // 5. 在指定位置显示一张40x40像素的图片 // gImage_1 是 pic.h 中定义好的图片数组 LCD_ShowPicture(160, 95, 40, 40, gImage_1); // 延时1秒,让变化看得清 delay_ms(1000); // 你可以尝试取消下面几行注释,看看全屏刷色的效果 // LCD_Fill(0,0,LCD_W,LCD_H,RED); // delay_ms(500); // LCD_Fill(0,0,LCD_W,LCD_H,GREEN); // delay_ms(500); // LCD_Fill(0,0,LCD_W,LCD_H,BLUE); // delay_ms(500); // LCD_Fill(0,0,LCD_W,LCD_H,WHITE); // delay_ms(500); } }

4.2 编译、烧录与上电

  1. 编译工程:在VS Code的ESP-IDF终端或你的项目目录下,运行idf.py build命令编译项目。
  2. 连接开发板:用USB线将ESP32-S3开发板连接到电脑,确保端口被系统识别。
  3. 烧录程序:运行idf.py -p PORT flash命令将程序烧录到开发板(将PORT替换为你的实际串口号,如COM3/dev/ttyUSB0)。
  4. 上电观察:烧录完成后,程序会自动运行。观察你的1.9寸屏幕:
    • 屏幕背光应该点亮。
    • 屏幕首先会全白。
    • 随后,屏幕上会显示“中电科”三个红字,以及屏幕的宽高参数(应该是170和320)。
    • 一个红色的浮点数会每秒增加0.11。
    • 屏幕右侧会显示一张内置的小图片。

如果一切顺利,恭喜你,驱动移植成功!如果屏幕没反应,别着急,可以按照下面的排查思路看看。

5. 常见问题与调试心得

搞嵌入式,一次成功是幸运,调试才是常态。这里分享几个我调试时遇到的问题和解决方法。

  • 屏幕完全无显示,背光也不亮

    • 检查电源:首先用万用表量一下屏幕VCC和GND引脚是不是3.3V。ESP32-S3的3.3V输出能力有限,如果接了很多外设,可能导致电压被拉低。
    • 检查背光:确认BLK引脚是否接对了。如果接的是GPIO,检查程序里是否将其设置为高电平输出;如果直接接3.3V,检查连接是否牢固。
    • 检查复位:测量RES引脚,正常工作时应该是高电平。可以在程序初始化前,手动给一个低电平脉冲(拉低再拉高)来复位屏幕。
  • 屏幕背光亮,但无任何内容(白屏或花屏)

    • 检查接线:这是最常见的问题!逐根线检查SCL、SDA、DC、CS是否与程序中的定义一一对应,有没有虚焊或接错。特别是DC和CS引脚,接反了肯定没显示。
    • 检查SPI模式:ST7789V3通常使用SPI Mode 0或Mode 3。确保驱动代码里的SPI模式设置正确。资料包里的驱动一般是设置好的,如果你用的其他驱动库,需要留意。
    • 降低SPI速度:尤其是软件SPI,如果初始化速度太快,屏幕可能反应不过来。尝试在初始化函数里,在发送初始化命令序列前,增加一个几十毫秒的延时(vTaskDelay(pdMS_TO_TICKS(50)))。
  • 显示内容错位、乱码或颜色不对

    • 检查屏幕扫描方向:ST7789V3可以通过命令设置扫描方向(Rotation)。驱动里一般有LCD_Display_Dir之类的函数。如果你发现文字是横着的或者镜像的,调用这个函数修改方向即可。
    • 检查颜色格式:ESP32-S3和屏幕可能使用不同的颜色格式(如RGB565、RGB888)。确保驱动中颜色数据的发送格式与屏幕期望的格式一致。资料包里的驱动通常已适配好。
  • 硬件SPI不工作,但软件SPI可以

    • 确认引脚复用:确保你为硬件SPI(SCLK, MOSI)分配的GPIO,在ESP32-S3上确实具有SPI功能。参考ESP32-S3的技术手册或引脚定义图。
    • 检查SPI控制器初始化:硬件SPI驱动中,除了配置引脚,还需要正确初始化SPI主机(spi_bus_initialize)和设备(spi_device_interface_config_t)。对比资料包里的硬件SPI驱动示例,看是否有遗漏步骤。

调试时,逻辑分析仪或者示波器是神器,可以抓取SPI总线上的波形,看时钟和数据有没有正常发出。没有仪器的话,就耐心点,用“二分法”排查:先确保电源和复位,再确保SPI数据线,最后看配置命令。

好了,关于ESP32-S3驱动1.9寸ST7789V3彩屏的教程就到这里。从硬件连接到软件移植,再到调试上电,整个过程走下来,你应该对SPI屏的驱动有了更实在的理解。这套驱动代码框架比较清晰,你完全可以在此基础上,去实现更复杂的UI、动画或者图形菜单。

http://www.jsqmd.com/news/471219/

相关文章:

  • ResNet 残差块设计解析:从恒等映射到网络深度优化
  • 【全志在线 x YuzukiHD】哪吒 D1s 开发板:基于RISC-V的智能解码AIoT核心板硬件与接口全解析
  • iOS蓝牙BLE外设名称缓存机制解析与实时更新策略
  • 创意无限:用EasyAnimateV5图生视频模型生成个性化短视频内容
  • Spring Kafka KafkaTemplate 异步与同步发送消息的实战对比及性能优化
  • 创维亮相AWE2026,AI科技+绿色生态擘画智慧生活新图景
  • 盘点靠谱的跨年焰火秀公司,专业表演焰火秀企业Top10 - myqiye
  • 从权重矩阵到视觉洞察:注意力热力图与柱状图的生成与解读全流程
  • 梁山派GD32F470驱动AHT10温湿度传感器:I2C时序与数据采集实战
  • Qwen2.5-0.5B-Instruct性能评测:边缘设备上的轻量大模型实战对比
  • 解码数字音频:从采样定理到量化精度的艺术
  • 能源化工场景:JS如何基于WebUploader实现生产数据大附件的秒传断点续传?
  • JavaScript基础课程三、 JavaScript入门与环境搭建
  • 水平平板速冻机(SolidWorks)
  • 深入解析RecyclerView(八)—RecyclerView的mAttachedScrap与mCachedViews缓存机制对比
  • 基于Tao-8k的智能代码生成器:提升Python与Java开发效率
  • 金胜车辆镀件厂镀硬铬加工经验丰富吗,价格贵不贵 - 工业品网
  • 【轻量超分实战】SPAN模型Pytorch源码解析与部署:从理论到高效训练
  • 第1、2课时
  • BEYOND REALITY Z-Image开箱即用体验:高清写实人像生成如此简单
  • SpringBoot如何实现HTTP大文件分片上传并支持军工领域的断点续传?
  • Nunchaku FLUX.1-dev 开发入门:从零开始编写第一个生成脚本
  • 基于Retinaface+CurricularFace的智能相册管理系统
  • Docker 部署神通数据库(Oscar)实战:从镜像拉取到许可证配置
  • VideoAgentTrek-ScreenFilter数据库设计实践:使用MySQL管理模型版本与审核策略
  • 5大核心功能解析:抖音视频批量下载工具的技术实现与行业应用
  • Qwen3-32B数据分析助手:用自然语言查询生成数据报告
  • 2026年好用的5310高压锅炉管推荐,附联系方式 - 工业设备
  • RMBG-2.0图文对话式抠图教程:拖拽上传→点击生成→右键保存全流程
  • 实战指南:基于快马平台生成电商级智能搜索框,集成分类与拼音下拉词