全栈自造 Status Deck(四):硬件终于到了,从点亮屏幕到跑通第一个 Demo
一、开篇:硬件终于到了
1.1 等待的焦虑与期待
在前几期文章中,我们完成了项目的整体规划和软件框架的初步设计。然而,硬件是这一切的基础------没有屏幕显示,没有处理器运行,再好的想法也只是空中楼阁。
快递信息从"已揽收"到"运输中",再到"派送中",每一天都在刷新物流状态。等待的过程中,脑子里不断闪过各种可能:
- 屏幕的驱动芯片到底好不好驱动?
- ESP32-S3 的性能够不够用?
- 接线会不会遇到兼容性问题?
这种等待既是焦虑,也是期待。终于,快递到了,拆开包裹的那一刻,项目正式进入"动真格"的阶段。
1.2 实验室现有设备盘点
在正式上手 ESP32-S3 之前,先来看看目前实验室手头有哪些设备可以利用:
| 设备 | 型号/规格 | 状态 | 用途 |
|---|---|---|---|
| 主控开发板 | ESP32-S3 | 已到货 | 用于前期验证及正式开发 |
| 显示屏幕 | 2.8 寸 TFT LCD | 已到货 | 主屏幕,用于 UI 显示 |
| 电源模块 | 可调稳压电源 | 常备工具 | 供电与调试 |
这些设备虽然不算豪华,但对于跑通第一个 Demo、验证整体方案可行性来说,已经完全够用了。
1.3 策略:直接使用 ESP32-S3 进行验证与开发
为什么选择直接使用 ESP32-S3 而不先用经典版?这是一个基于项目需求和芯片特性的决定:
- 性能匹配:ESP32-S3 的双核 LX7 处理器、更大的 PSRAM 以及 AI 加速能力,更符合 Status Deck 未来可能涉及的数据处理和复杂 UI 渲染需求。
- 原生 USB 支持:ESP32-S3 支持 USB OTG,为后续可能的 USB 外设扩展或固件更新提供了便利,这是经典版不具备的优势。
- 一步到位:既然最终目标就是 S3,直接使用它可以避免从经典版迁移时可能遇到的适配问题,节省后期移植时间。
- 生态成熟:ESP32-S3 作为较新的芯片,其开发生态(如 ESP-IDF、Arduino 支持)已经非常完善,遇到问题同样有丰富的社区资源可供参考。
简单来说,ESP32-S3 的性能与特性更契合本项目的长期目标,且其开发环境已足够成熟,直接上手是高效且务实的选择。
二、硬件介绍
2.1 ESP32-S3 开发板
本次测试与开发的主控是 ESP32-S3 开发板。作为乐鑫 ESP32 系列的高性能成员,它不仅继承了 ESP32 家族出色的无线连接能力和低功耗特性,还通过引入 AI 加速指令和更丰富的外设接口,为物联网与边缘计算应用提供了强大支持。
核心参数
| 参数 | 规格 |
|---|---|
| 主控芯片 | ESP32-S3 |
| CPU | Xtensa® 双核 32 位 LX7 处理器,主频最高 240 MHz |
| 内存 | 512 KB SRAM + 8 MB PSRAM(视具体模组) |
| Flash | 外置 SPI Flash,通常为 4 MB 或 8 MB |
| Wi-Fi | 802.11 b/g/n,2.4 GHz |
| 蓝牙 | Bluetooth 5.0 LE |
| USB | 原生 USB OTG |
| AI 加速 | 支持向量指令扩展 |
| 工作电压 | 3.0 ~ 3.6 V(开发板通过 USB 可输出 5V/3.3V) |
为什么选择这款芯片
选择 ESP32-S3 作为本项目的主控,主要基于以下几点考虑:
- 性能充足:双核 LX7 处理器主频高达 240 MHz,配合 8 MB PSRAM,能够轻松应对 TFT 屏幕驱动、UI 渲染以及后续可能加入的数据处理任务。
- AI 加速:内置的向量指令扩展为未来可能涉及的轻量级机器学习推理(如状态识别、预测)提供了硬件加速基础,无需外挂专用 AI 芯片。
- 原生 USB:支持 USB OTG,方便进行固件烧录、调试,甚至未来可连接 USB 外设,扩展性强。
- 低功耗与无线集成:在提供高性能的同时,依然保持了 ESP32 系列优秀的低功耗特性和稳定的 2.4 GHz Wi-Fi / BLE 5.0 连接能力,非常适合物联网项目。
- 开发生态完善:Espressif 为 S3 提供了完善的 ESP-IDF 开发框架,同时 Arduino IDE 和 PlatformIO 也提供了良好支持,社区资源和示例代码丰富。
简单总结就是:性能强、接口全、生态好。它为 Status Deck 项目提供了从原型验证到功能扩展的坚实硬件基础。



2.2 2.8寸显示屏幕
屏幕是整个项目的"脸面"------所有数据展示、UI 交互、状态反馈都要通过它呈现。本次选用的是一块 2.8 寸 ST7789 SPI 串口 TFT LCD 显示屏 ,价格仅 18 元,性价比极高。
基本规格
| 参数 | 规格 |
|---|---|
| 屏幕尺寸 | 2.8 英寸 |
| 显示类型 | TFT LCD(薄膜晶体管液晶显示器) |
| 分辨率 | 240 × 320 像素(QVGA) |
| 驱动芯片 | ST7789V |
| 接口类型 | SPI(4 线串行) |
| 工作电压 | 3.3V(部分模块板载 3.3V 稳压,可兼容 5V) |
| 触摸功能 | 无(本次项目仅用于显示) |
| 购买价格 | 18 元 |

为什么选择这个屏幕
在选型阶段,其实考虑过几种方案:
| 屏幕类型 | 优点 | 缺点 | 选择结果 |
|---|---|---|---|
| OLED 0.96 寸 | 驱动简单、功耗低 | 尺寸太小,信息展示有限 | ❌ |
| TFT 1.8 寸 | 体积小巧 | 分辨率低,显示面积小 | ❌ |
| TFT 2.8 寸 | 尺寸合适、分辨率够用、价格便宜 | 不支持触摸 | ✅ 选择 |
| TFT 3.5 寸 | 显示面积大 | 分辨率提升不明显,体积偏大 | ❌ |
综合考虑项目需求(状态展示面板)和空间限制(需要集成到桌面设备中),2.8 寸是一个尺寸与便携性的最佳平衡点。240×320 的分辨率足以显示多行文字、图表和图标,同时 18 元的价格也让试错成本降到最低。

2.3 屏幕驱动转接板
裸屏无法直接连接 ESP32 进行开发。这类 2.8 寸 TFT 屏幕通常通过 FPC 排线引出大量引脚,排线间距非常小,普通杜邦线和面包板根本无法直接对接。因此,本项目额外搭配了一块 LCD 屏幕驱动转接板,由屏幕店家配套出售。
转接板的作用
转接板将 FPC 排线的细密引脚转换为标准 2.54mm 间距的排针接口,使得杜邦线可以直接连接 ESP32 开发板,极大简化了接线流程。

实际到货情况
本次购买的屏幕不带触摸功能,因此转接板上与触摸相关的引脚(如 T_IRQ、T_DO、T_DIN、T_CS、T_CLK)处于悬空或未焊接状态。到货时,转接板已与屏幕通过 FPC 排线连接完毕,无需自行组装,可直接使用杜邦线与 ESP32 连接。

价格:8 元
2.4 电源模块
为什么需要独立电源
ESP32 开发板的板载 3.3V 稳压器虽然可以输出一定电流,但对于驱动 2.8 寸 TFT 屏幕这类外设来说,供电能力可能略显不足------尤其是在屏幕显示复杂内容或高亮度时,电流需求会明显增加。供电不稳轻则导致屏幕闪烁、颜色异常,重则导致 ESP32 反复重启。
多路电源模块的优势
为了确保供电稳定可靠,我额外使用了一块多路电源模块。它能提供独立的 3.3V 和 5V 输出,不仅满足屏幕的供电需求,还能同时为传感器、LED 等其他外设供电。多路独立输出也便于调试时隔离不同模块的电源,方便排查问题。
需要注意的是,电源模块是可选的。 如果开发场景比较简单且屏幕工作正常,可以直接使用开发板的板载 3.3V 供电。电源方案的选择取决于实际需求和测试情况,本文仅作为参考。


三、硬件连接:让屏幕与 ESP32 对话
3.1 接线方案
本次连接共使用 8 根杜邦线,将屏幕与 ESP32-S3 开发板连接。按屏幕排针从下到上的顺序,接线如下:
| 屏幕引脚 | 功能说明 | 连接到 ESP32-S3 引脚 |
|---|---|---|
| VCC | 电源正极 | 3V3 |
| GND | 电源地 | GND |
| CS | 片选 | IO5 |
| RESET | 复位 | IO7 |
| DC | 数据/命令选择 | IO6 |
| SDI (MOSI) | 主设备输出,从设备输入 | IO17 |
| SCK | SPI 时钟 | IO18 |
| LED | 背光控制 | IO4 |
| SDO (MISO) | 主设备输入,从设备输出 | 不接 |
注意事项:
- 屏幕的 SDO (MISO) 引脚在本项目中不需要连接,因为仅进行屏幕驱动,不读取屏幕数据。
- 触摸接口
T_IRQ/T_SDO/T_SDI/T_CS/T_CLK全部不接,因为本屏幕不带触摸功能。 - 所有连接线请确保牢固,避免接触不良导致屏幕工作异常。
3.2 连接实物图
接线完成后的实物展示如下图所示。可以清晰地看到杜邦线从屏幕转接板连接到 ESP32-S3 开发板的对应引脚。


建议在接线完成后仔细检查每一根线的连接是否正确,特别是电源和地线,避免接反导致硬件损坏。
四、开发环境搭建
4.1 开发工具选择:PlatformIO
在开发工具的选择上,本项目采用 PlatformIO 作为主要的集成开发环境(IDE)和构建系统。
为什么选择 PlatformIO
虽然 Arduino IDE 上手简单,但在实际项目开发中,PlatformIO 具有明显优势:
| 对比项 | Arduino IDE | PlatformIO |
|---|---|---|
| 依赖管理 | 手动安装库,版本难以控制 | platformio.ini 统一管理,版本锁定 |
| 项目结构 | 扁平化,所有文件堆在一起 | 标准化目录结构,清晰规范 |
| 多环境构建 | 不支持 | 支持多环境配置,一键切换 |
| 代码补全 | 基础支持 | 基于 IntelliSense,补全体验优秀 |
| 版本控制 | 不友好 | 原生支持 Git,便于协作 |
| 调试支持 | 有限 | 支持 OpenOCD 等调试器,功能强大 |
对于 Status Deck 这样需要长期迭代的项目,PlatformIO 的工程化管理能力能有效避免后期"配置地狱"。
PlatformIO 安装
PlatformIO 以 VS Code 扩展的形式提供,安装步骤如下:
- 在 VS Code 中搜索并安装 PlatformIO IDE 扩展
- 扩展安装完成后,侧边栏会出现 PlatformIO 的图标
- 首次使用时,PlatformIO 会自动安装核心工具链(PlatformIO Core)

提示:如果网络环境不佳,安装核心工具链可能较慢,可参考官方文档配置镜像源。
ESP32-S3 开发板支持包安装
PlatformIO 通过 Board 定义文件管理开发板支持。对于 ESP32-S3,需要安装对应的平台包:
- 打开 PlatformIO 主页,进入 Boards 搜索页面
- 搜索
esp32-s3,可以看到多种 ESP32-S3 开发板定义 - 根据实际使用的开发板型号选择对应的 Board 配置
在 platformio.ini 中,Board 配置示例如下:
ini
[platformio]
boards_dir = boards
default_envs = esp32-s3-n16r8
; Status Deck 固定使用 ESP32-S3 N16R8:16MB Flash + 8MB Octal PSRAM。
; 执行 `pio run -t upload` 会直接构建并烧录这个目标。
[env:esp32-s3-n16r8]
platform = espressif32
board = esp32-s3-n16r8
framework = arduino
monitor_speed = 115200
upload_speed = 921600
lib_deps =
h2zero/NimBLE-Arduino@^1.4.3
bblanchon/ArduinoJson@^6.21.5
adafruit/Adafruit GFX Library@^1.12.3
adafruit/Adafruit ST7735 and ST7789 Library@^1.11.0
build_flags =
; 2.8 英寸 ST7789 SPI 屏。N16R8 的 GPIO26-32 被板载 Flash/PSRAM 使用,
; 因此只选开发板排针上可用的 GPIO4-7、17、18;GPIO19/20 留给原生 USB。
-D STATUS_DECK_DISPLAY_CS=5
-D STATUS_DECK_DISPLAY_DC=6
-D STATUS_DECK_DISPLAY_RESET=7
-D STATUS_DECK_DISPLAY_BACKLIGHT=4
-D STATUS_DECK_DISPLAY_SCK=18
-D STATUS_DECK_DISPLAY_MOSI=17
-D STATUS_DECK_DISPLAY_SPI_FREQUENCY=40000000
-D STATUS_DECK_ACTIVITY_LED_PIN=2
五、跑通第一个 Demo
完成 ESP32-S3、ST7789 屏幕接线与 PlatformIO 工程配置后,先通过一个简单的屏幕 Demo 验证三件事:
- ESP32-S3 的 SPI 引脚接线正确
- ST7789 屏幕可以正常初始化
- 屏幕能够完成颜色填充、文字与图形绘制
本项目使用 240 × 320 分辨率的 ST7789 SPI 彩屏,并为 ESP32-S3 N16R8 配置了 16MB Flash 和 8MB Octal PSRAM。PSRAM 用于存放完整帧缓冲,后续可以减少动态数据刷新时的闪烁。
5.1 Demo 功能设计
第一个 Demo 包含以下内容:
- 黑色背景初始化
- 红、绿、蓝三种颜色块填充测试
- 标题文字显示
- 简单矩形和进度条绘制
- 背光控制测试
屏幕使用的引脚定义如下:
| 屏幕引脚 | ESP32-S3 GPIO |
|---|---|
| VCC | 3V3 |
| GND | GND |
| CS | GPIO5 |
| RESET | GPIO7 |
| DC | GPIO6 |
| SDI / MOSI | GPIO17 |
| SCK | GPIO18 |
| LED | GPIO4 |
| SDO / MISO | 不接 |
注意:ESP32-S3 N16R8 的 GPIO26 至 GPIO32 被 Flash 和 PSRAM 占用,不能沿用经典 ESP32 的 GPIO26、GPIO27 接法。
5.2 Demo 完整代码
在当前工程中,屏幕初始化与绘制逻辑位于:
firmware/src/display/StatusDisplay.cppfirmware/include/display/StatusDisplay.hfirmware/src/app/main.cpp
下面是一份可独立理解的最小 Demo 核心代码:
cpp
#include <Arduino.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7789.h>
constexpr int TFT_CS = 5;
constexpr int TFT_DC = 6;
constexpr int TFT_RST = 7;
constexpr int TFT_BL = 4;
constexpr int TFT_SCK = 18;
constexpr int TFT_MOSI = 17;
Adafruit_ST7789 display(TFT_CS, TFT_DC, TFT_RST);
void setup() {
Serial.begin(115200);
// ESP32-S3 使用自定义 SPI 引脚。
SPI.begin(TFT_SCK, -1, TFT_MOSI, TFT_CS);
// 打开屏幕背光。
pinMode(TFT_BL, OUTPUT);
digitalWrite(TFT_BL, HIGH);
// 初始化 240 x 320 的 ST7789 屏幕。
display.init(240, 320);
display.setRotation(0);
display.setSPISpeed(40000000);
display.setTextWrap(false);
// 背景填充测试。
display.fillScreen(ST77XX_BLACK);
// 颜色块测试。
display.fillRect(16, 50, 64, 64, ST77XX_RED);
display.fillRect(88, 50, 64, 64, ST77XX_GREEN);
display.fillRect(160, 50, 64, 64, ST77XX_BLUE);
// 文字显示测试。
display.setTextColor(ST77XX_WHITE);
display.setTextSize(2);
display.setCursor(16, 16);
display.println("Status Deck");
display.setTextSize(1);
display.setCursor(16, 140);
display.println("ESP32-S3 + ST7789");
// 简单进度条测试。
display.drawRect(16, 180, 208, 20, ST77XX_WHITE);
display.fillRect(18, 182, 140, 16, ST77XX_CYAN);
display.setCursor(16, 220);
display.println("Display demo ready.");
}
void loop() {
// 第一个 Demo 不需要循环刷新。
}
5.3 编译与烧录
进入固件目录后执行:
cd firmware
pio run -t upload
串口监视器可使用:
pio device monitor -b 115200
正常启动时,串口会输出类似信息:
ST7789 framebuffer ready: 153600 bytes
ST7789 ready: CS=5 DC=6 RESET=7 BL=4 SPI=40000000Hz
其中 153600 bytes 表示已经成功申请到一块 240 × 320 × 2 字节的 RGB565 帧缓冲。
5.4 运行效果展示
烧录成功后,屏幕应当显示:
- 顶部白色标题 Status Deck
- 中间的红、绿、蓝三个颜色块
- 一条青色进度条
- 底部的 Display demo ready. 文本
如果背光亮起但屏幕没有内容,优先检查:
- CS、DC、RESET 是否接错。
- SCK 是否接到 GPIO18,MOSI 是否接到 GPIO17。
- 屏幕供电是否为 3.3V,并且 ESP32-S3 与屏幕已经共地。
- LED 是否接到 GPIO4;如果未接,屏幕背光可能不会亮。
- 将 SPI 频率从 40000000 降低到 32000000 后重新测试。
实际调试说明:当前阶段并没有逐步演示上述基础 Demo 的运行过程,而是直接将所有功能整合到最终效果中进行展示。这样做的原因在于------基础的颜色块填充、文字显示等测试步骤属于验证性质,而项目真正要呈现的是一个完整的状态面板。因此在确认硬件接线与 SPI 通信无误后,便直接推进到了最终效果的调试阶段。以下就是实际烧录后的屏幕效果:


从上面的实拍图可以看到,屏幕已经能够正常显示完整的状态面板界面,包括各项数据指标和布局排版。这标志着硬件层面已经完全跑通------ESP32-S3 可以通过 SPI 驱动 ST7789 屏幕,完成任意 UI 元素的渲染。这个里程碑的达成,为后续的固件功能开发打下了坚实的基础。
5.5 调试过程中的经验总结
在从接线到最终效果跑通的过程中,踩了不少坑,这里把关键经验总结出来,供后续开发或类似项目参考:
- 先验证最简通信 :拿到屏幕后不要急着上最终效果,先用
fillScreen()填满纯色确认 SPI 通信正常,再逐步叠加文字、图形等功能。 - GPIO 选择要注意引脚复用:ESP32-S3 的部分 GPIO 被板载 Flash 和 PSRAM 占用(GPIO26-32),选引脚时务必查阅开发板的引脚映射表,避免使用被占用的引脚。
- 供电要充足:屏幕背光全亮时电流需求不低,如果同时外接其他传感器,建议使用独立电源模块供电,或者至少确认开发板的 LDO 能够承受总电流。
- SPI 频率不要贪高:初次调试建议先使用 20MHz 或 30MHz,确认稳定后再逐步提升到 40MHz。杜邦线的接触质量会直接影响高频 SPI 的稳定性。
- 串口日志是好帮手:在初始化阶段加入 Serial.println 输出,可以帮助快速定位问题出在哪个环节------是 SPI 初始化失败、屏幕 ID 读取异常还是显示方向设置错误。
六、本篇总结与下期预告
6.1 本篇做了什么
回顾本篇文章,我们完成了以下里程碑:
- ✅ 硬件到货与设备盘点:确认 ESP32-S3 开发板、2.8 寸 ST7789 屏幕、转接板、电源模块全部到位。
- ✅ 硬件连接:完成 8 线杜邦线接线,屏幕与 ESP32-S3 正确对接。
- ✅ 开发环境搭建:配置 PlatformIO 工程,定义引脚宏、库依赖和编译参数。
- ✅ 第一个 Demo 跑通:屏幕成功点亮并显示完整的状态面板界面,验证了 SPI 通信、屏幕驱动、UI 渲染全链路正常工作。
从"快递到了"到"屏幕亮了",这看起来只是简单的几步,但每一步都承载着前期大量的规划和设计。硬件的跑通意味着项目从"纸上谈兵"正式进入了"实战阶段"。
6.2 遇到的问题与解决思路
整个过程中并非一帆风顺,主要遇到的问题包括:
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 屏幕白屏无显示 | DC 引脚接错 | 对照引脚表重新核对接线 |
| 屏幕有背光但无内容 | SPI 频率过高导致通信不稳定 | 降低 SPI 频率至 20MHz 后恢复正常 |
| 显示方向不正确 | setRotation() 参数值不对 |
调整旋转参数(0-3)直到方向正确 |
| 串口无输出 | 波特率不匹配 | 统一使用 115200 波特率 |
这些问题虽然看似基础,但却是每个嵌入式项目初期都会遇到的典型障碍。记录下来,既能帮助自己复盘,也能为后来者提供参考。
6.3 下期预告
本篇解决了"屏幕能不能亮"的问题,下一篇文章将深入解决"屏幕应该显示什么"的问题。
下期内容规划:
- ESP32-S3 固件项目工程详解:完整的项目目录结构、模块划分与构建配置
- 核心代码讲解:从屏幕初始化、UI 框架搭建到数据渲染的完整代码走读
- 状态面板 UI 设计:如何在 240×320 的小屏幕上合理布局,展示尽可能多的有效信息
- 数据通路打通:ESP32-S3 如何获取状态数据并驱动屏幕刷新
本篇文章所有的项目工程代码已在 GitHub 上开源:

欢迎 Star 和 Fork,也欢迎在 Issue 区交流讨论。如果觉得本系列文章对你有帮助,别忘了关注后续更新 👋