项目标题里的 ESP32S31,大概率是把 ESP32-S3 多打了一个 1。名称不准确没关系,核心问题是这颗芯片驱动屏幕之后的实际刷屏表现:点亮顺不顺、刷新卡不卡、内存够不够、批量测试能不能自动化。这篇文章按实际项目推进顺序来写,先回答能不能用,再给出接线、编译、烧录、测试和排错的全套操作。
这次验证以一块常见的 SPI 屏为例,比如 ST7789 驱动的 240x320 屏幕。同样流程适用于 ILI9341、ST7735、GC9A01 等驱动 IC 的屏;如果你用的是 RGB 接口屏,思路不变,但接线和显存策略要调整。你不需要现在就有 LVGL 基础,我会先给一个不依赖复杂图形库的刷屏测试程序,再在此基础上加串口命令、批量烧录和性能观察。
读完你至少能知道:自己的板子和屏能不能点亮、刷一帧大概耗时多少、卡顿主要卡在哪一步、多块板子批量烧录怎么处理。这篇文章适合刚拿到 ESP32-S3 开发板,想快速验证屏幕效果的嵌入式开发者,也适合准备把屏幕功能做进产品的前期选型。
1. 核心能力速览
| 能力项 | 说明 |
|---|---|
| 芯片型号 | ESP32-S3,题目里的 ESP32S31 大概率是笔误 |
| 处理器 | 双核 Xtensa LX7,公开规格显示主频可达 240 MHz |
| 内存配置 | 内置 SRAM;常见模组分为不带 PSRAM、带 2MB/8MB/16MB PSRAM 等版本,以实际购买型号为准 |
| Flash | 常见 4MB / 8MB / 16MB,以具体模组丝印和购买页参数为准 |
| 显示接口 | SPI、并行 8080、RGB 等;常见 SPI 驱动 IC 有 ST7789、ILI9341、ST7735、GC9A01 |
| 典型分辨率 | 240x240、240x320、320x480、480x272 等,取决于屏幕类型和驱动方式 |
| 开发方式 | Arduino IDE、VS Code + PlatformIO、ESP-IDF |
| 图形库 | TFT_eSPI、Arduino_GFX、LovyanGFX、LVGL |
| 调试方式 | 串口日志、Web 控制、逻辑分析仪测 SPI 时序 |
| 批量能力 | 支持批量烧录、串口批量测试、多板自动化 |
| 适合场景 | 桌面摆件、传感器数据面板、智能家居控制面板、小型人机交互屏 |
再强调一点:刷屏效果不只看芯片,屏幕接口、SPI 频率、是否开 RGB 接口、是否用 PSRAM,都会影响体验。所以后面测试的目标是“在固定硬件配置下,找到一组能稳定运行的参数”。
2. 适用场景与使用边界
2.1 适合谁
- 快速原型验证:用 Arduino 或 PlatformIO 点亮屏幕,验证显示方案是否可行。
- 小型 UI 面板:温湿度计、时钟、开关面板、桌面卡片屏。
- 批量产测:多块板子批量烧录,批量跑刷屏用例。
- LVGL 交互界面:滚轮菜单、仪表盘、简单触摸交互。
2.2 不适合什么
不要指望它在 1080P RGB 屏上做复杂视频级界面,内存和总线带宽都不够。没有 PSRAM 的版本,跑大分辨率的 LVGL 界面会非常紧张。复杂动效、大图片、大量本地字体,都需要提前考虑资源优化,否则刷屏会明显变卡。
2.3 使用边界与合规提醒
使用 TFT_eSPI、LVGL 等开源库时,注意对应的开源许可证。屏幕取模工具生成的 C 数组,如果来自第三方固件或商业方案,需要确认授权。产品中如果涉及用户数据、人脸、声音等隐私内容,按相关法规处理。测试固件不要直接拿到产线批量刷写,先保证引脚定义和电源设计经过验证。
3. 环境准备与前置条件
3.1 硬件清单
- ESP32-S3 开发板 1 块,最好带 USB 串口芯片,例如 CP2102 或 CH340。
- SPI 屏幕 1 块,本文以 ST7789 的 240x320 为例。
- 杜邦线若干,用于连接开发板和屏幕。
- USB 数据线 1 根,注意部分线只能供电不能传数据。
- 可选:面包板、独立 3.3V 电源模块。
如果屏幕是 5V 供电版本,需要单独处理电平转换,不要直接把 5V 引脚接到 ESP32-S3 的 3.3V 系统上。
3.2 接线关系
SPI 屏幕常见引脚定义:
- VCC -> 3.3V
- GND -> GND
- SCL / SCK / CLK -> SPI 时钟
- SDA / MOSI / DIN -> SPI 数据
- CS -> 片选
- DC / RS -> 数据/命令选择
- RES / RST -> 复位
- BLK / LED -> 背光控制
以下是示例接线,不代表所有开发板都适用,请以你手上的板子丝印和原理图为准。
| 屏幕引脚 | ESP32-S3 GPIO | 备注 |
|---|---|---|
| VCC | 3V3 | 确认模块支持 3.3V |
| GND | GND | 必须共地 |
| SCL | GPIO12 | SPI Clock |
| SDA | GPIO11 | SPI MOSI |
| CS | GPIO10 | 片选 |
| DC | GPIO9 | 数据/命令选择 |
| RST | GPIO8 | 复位 |
| BLK | GPIO7 | 背光,也可直接接 3V3 |
接线完成后,先量一遍 VCC 和 GND 是否短路,避免上电烧模块。
3.3 软件准备
- Arduino IDE 2.x 或 VS Code + PlatformIO 插件。
- ESP32 开发板支持包,即 Arduino 的 esp32 by Espressif。
- TFT_eSPI 库,用于 SPI 屏幕驱动。
- LVGL 库,做复杂 UI 时使用。
- 串口驱动:CP210x 或 CH340 对应驱动。
准备过程中先确认三件事:
- 系统能否识别 USB 串口,Windows 下对应 COM 号,Linux 下通常是 /dev/ttyUSB0。
- 开发板指示灯是否正常,供电是否稳定。
- 数据线是否真的支持数据传输,而不是纯充电线。
4. 安装部署与启动方式
4.1 选择开发方式
| 开发方式 | 优点 | 缺点 |
|---|---|---|
| Arduino IDE | 上手快,库多,适合快速验证 | 工程管理弱,复杂 UI 调试不便 |
| VS Code + PlatformIO | 工程化,依赖清晰,批量烧录方便 | 首次下载工具链时间较长 |
| ESP-IDF | LVGL 集成度高,适合产品级开发 | 学习成本高,需要更多配置 |
如果只是验证刷屏效果,推荐 PlatformIO。它能把库依赖写入工程配置文件,换一台电脑也能很快恢复环境。
4.2 PlatformIO 工程示例
在 VS Code 里创建新工程,platformio.ini可以写成这样:
[env:esp32-s3-devkitc-1] platform = espressif32 board = esp32-s3-devkitc-1 framework = arduino monitor_speed = 115200 lib_deps = bodmer/TFT_eSPI说明:
board要根据自己的开发板型号调整。- 第一次编译会下载工具链和库,耐心等待。
monitor_speed是串口监视器的波特率,要和代码里的Serial.begin(115200)一致。
4.3 TFT_eSPI 引脚配置
TFT_eSPI 默认有一套引脚配置,但不同开发板差异很大。推荐改动工程配置,而不是去改库文件里的User_Setup.h。
在platformio.ini中追加:
build_flags = -DUSER_SETUP_LOADED=1 -DST7789_DRIVER=1 -DTFT_WIDTH=240 -DTFT_HEIGHT=320 -DTFT_MOSI=11 -DTFT_SCLK=12 -DTFT_CS=10 -DTFT_DC=9 -DTFT_RST=8 -DTFT_BL=7 -DSPI_FREQUENCY=40000000这里的引脚是示例,必须按 3.2 节的接线表修改。如果出现花屏,优先降低SPI_FREQUENCY,比如改成 20000000。
如果用 Arduino IDE,可以直接编辑库目录下的User_Setup.h,步骤类似,但不同版本库文件位置不一样。
4.4 烧录与运行
在 PlatformIO 中点击 Upload,或命令行执行:
pio run -t upload烧录完成后打开串口监视器:
pio device monitor如果上传失败,通常是进入下载模式的问题。按住 BOOT 键,同时按一下 RESET,松开 BOOT,再上传一次。
烧录完成后,屏幕应该能点亮并显示内容,串口能正常输出日志。到这里,基础运行链路已经通了。
5. 功能测试与效果验证
5.1 基础点亮测试
目的:验证屏幕能否正常初始化、背光是否工作、颜色填充是否正确。
测试代码:
#include <TFT_eSPI.h> TFT_eSPI tft = TFT_eSPI(); uint16_t testColors[] = {TFT_RED, TFT_GREEN, TFT_BLUE, TFT_WHITE, TFT_BLACK}; const char* colorNames[] = {"RED", "GREEN", "BLUE", "WHITE", "BLACK"}; void setup() { Serial.begin(115200); tft.init(); tft.setRotation(1); tft.fillScreen(TFT_BLACK); } void loop() { for (int i = 0; i < 5; i++) { tft.fillScreen(testColors[i]); tft.setTextColor(testColors[i] == TFT_BLACK ? TFT_WHITE : TFT_BLACK, testColors[i]); tft.setCursor(10, 10); tft.setTextFont(4); tft.print(colorNames[i]); delay(500); } }预期结果:红、绿、蓝、白、黑五色切换正常,颜色均匀,没有花屏和闪烁。
判断标准:
- 颜色边界清晰。
- 字符位置正确。
- 背光无频闪。
如果白屏,先查背光引脚和复位时序。如果花屏,先查接线,再降低 SPI 频率。
5.2 文字显示测试
目的:确认屏幕旋转方向、英文字体显示和位置坐标。
操作步骤:
- 用
setRotation(0)到setRotation(3)切换方向,观察文字方向是否和屏幕安装方向一致。 - 用
drawString或print显示数字、字母、符号。 - 如果显示中文,TFT_eSPI 默认不自带中文字库,需要用取模工具生成字模,或者改用 LVGL 加载字库。
预期结果:
- 英文字符清晰。
- 字符间距正常。
- 旋转后的坐标符合预期。
5.3 滚动刷屏与帧耗时测试
目的:观察高频刷新时是否卡顿,并量化每帧耗时。
代码:
#include <TFT_eSPI.h> TFT_eSPI tft = TFT_eSPI(); void setup() { Serial.begin(115200); tft.init(); tft.setRotation(1); tft.fillScreen(TFT_BLACK); tft.setTextFont(4); } void loop() { static uint32_t counter = 0; uint32_t start = millis(); tft.fillScreen(TFT_NAVY); tft.setTextColor(TFT_WHITE, TFT_NAVY); tft.setCursor(10, 20); tft.print("ESP32-S3 Screen"); tft.setTextColor(TFT_YELLOW, TFT_NAVY); tft.setCursor(10, 80); tft.print("Count: "); tft.println(++counter); uint32_t elapsed = millis() - start; uint32_t fps = 1000 / (elapsed > 0 ? elapsed : 1); tft.setTextColor(TFT_GREEN, TFT_NAVY); tft.setCursor(10, 140); tft.print("Frame ms: "); tft.println(elapsed); Serial.printf("frame: %u ms, fps: %u\n", elapsed, fps); delay(100); }预期结果:
- 屏幕上的计数器持续递增。
- 串口输出能看到每帧耗时。
- 数值没有突变,说明刷新稳定。
如果帧耗时明显波动,要检查是否有其他任务抢占 CPU,比如 Wi-Fi 连接或日志输出。高频刷屏时,太频繁的Serial.printf本身就会影响帧耗时。
5.4 LVGL 界面切换测试
如果准备接入 LVGL,不要一上来就做复杂界面,先创建两个页面,自动交替切换。
操作步骤:
- 初始化 LVGL 和屏幕