手把手教你用Arduino点亮ST7789彩屏:从接线到显示的完整实战指南
你有没有遇到过这样的情况?买了一块漂亮的1.3英寸彩色TFT屏幕,兴冲冲插上Arduino,结果屏幕要么不亮、要么花屏、文字倒着显示……最后只能束之高阁?
别担心,这几乎是每个嵌入式新手都会踩的坑。而这块“难搞”的屏幕,很可能就是ST7789驱动的TFT液晶模块。
今天我们就来彻底解决这个问题——不是走马观花地贴代码,而是带你真正理解它的工作原理,从硬件连接、SPI通信细节,再到软件配置和调试技巧,一步步把这块小彩屏“驯服”。
为什么是ST7789?一块值得掌握的小屏
在如今动辄几寸大屏的时代,为什么我们还要关注一块240×240分辨率的小屏幕?
因为它的应用场景太广泛了:
- 智能手表原型
- WiFi信号扫描仪
- 温湿度监测面板
- 迷你游戏机
- 音频频谱可视化
而ST7789正是这些项目背后最常见的“显卡”。它支持RGB565色彩格式(65K色),自带GRAM显存,仅需SPI四线即可驱动,功耗低、价格便宜,且有成熟的开源库支持。
更重要的是:一旦你搞懂了ST7789,你就掌握了绝大多数TFT屏的核心逻辑。
ST7789到底是什么?不只是一个“控制器”
简单说,ST7789是一个LCD驱动IC,负责把MCU发来的图像数据转换成液晶像素的明暗与颜色。但它不是孤军奋战,内部集成了多个关键模块:
- GRAM(图形RAM):240×240×16位 = 约150KB内存,用于存储当前画面。
- DC/DC升压电路:为LCD提供所需的偏置电压,部分型号只需3.3V供电。
- SPI接口引擎:解析来自主控的命令和数据流。
- 地址映射单元:决定像素如何排列在屏幕上(影响旋转方向)。
这意味着你不需要外接显存,也不需要复杂的电源设计——对Arduino这类资源有限的平台非常友好。
它怎么工作的?四个步骤讲清楚
- 复位:通过RST引脚拉低再释放,让芯片回到初始状态;
- 初始化:发送一系列“魔法指令”配置颜色格式、进入正常模式;
- 写命令或数据:用D/C引脚切换模式,告诉ST7789“接下来是控制指令还是像素点”;
- 刷新GRAM:将图像数据通过SPI写入指定区域,屏幕自动更新。
听起来不复杂,但实际中最容易出问题的地方,往往藏在细节里。
SPI通信:别被“串行”两个字骗了
很多人以为SPI就是简单的“发数据”,其实不然。ST7789使用的是一种类SPI协议,虽然物理上用了SCK、MOSI、CS三根标准SPI线,但必须配合D/C和RST才能完整控制。
四根线+两个脚,缺一不可
| 引脚 | 作用 | 是否必需 |
|---|---|---|
| SCK | 时钟同步 | ✅ 必须 |
| MOSI | 主机发送数据 | ✅ 必须 |
| CS | 片选,低电平启用 | ✅ 建议连接 |
| DC | 区分命令/数据 | ✅ 必须! |
| RST | 复位芯片 | ⚠️ 可省略但不推荐 |
| VCC/GND | 供电 | ✅ 必须 |
🔥 特别提醒:DC引脚至关重要!如果你发现屏幕初始化成功却无法显示内容,八成是DC没接对。
SPI模式必须是Mode 3!
这是很多初学者翻车的第一关。
ST7789要求SPI工作在Mode 3,即:
- CPOL = 1 → 时钟空闲时为高电平
- CPHA = 1 → 在第二个边沿采样
如果你的开发板默认不是这个模式(比如某些ESP8266核心),就会导致通信失败。
幸运的是,大多数Arduino库会自动设置正确模式,但我们仍需心里有数。
实际传输过程长什么样?
假设我们要画一个红色像素:
tft.drawPixel(100, 100, ST7789_RED);背后发生了什么?
- 拉低CS,选中设备;
- 设置DC=0,准备发命令;
- 发送
0x2A(列地址设置); - 设置DC=1,开始发数据;
- 发送起始X坐标高位和低位;
- 再次设置DC=0,发
0x2B(页地址设置); - 设置DC=1,发送Y坐标;
- 发
0x2C(写GRAM); - 设置DC=1,连续发送两个字节:
0xF8, 0x00(RGB565红色值); - 拉高CS,结束传输。
看到没?哪怕只是画一个点,也要经历多次命令切换。这也是为什么频繁刷新会导致性能下降的原因。
硬件接线实战:以ESP32为例
下面这张表是你最该收藏的部分。我们以最常见的ESP32 DevKit V1+ST7789 240x240模块为例:
| ST7789引脚 | 推荐连接 | 说明 |
|---|---|---|
| VCC | 3.3V | ❌ 绝对不能接5V!会烧毁! |
| GND | GND | 共地是通信基础 |
| SCL/SCK | GPIO18 | 硬件SPI_SCK |
| SDA/MOSI | GPIO23 | 硬件SPI_MOSI |
| RES/RST | GPIO4 | 软件可控复位 |
| DC | GPIO2 | 控制命令/数据切换 |
| CS | GPIO5 | 片选,可与其他SPI设备共享 |
📌 提示:ESP32的硬件SPI引脚是固定的(18-SCK, 23-MOSI),不要随意更改。
如果你使用的是Arduino Uno,由于其SPI引脚固定(13-SCK, 11-MOSI),接线如下:
| ST7789引脚 | Uno引脚 |
|---|---|
| SCK | 13 |
| MOSI | 11 |
| CS | 10(或其他数字口) |
| DC | 9 |
| RST | 8 |
注意:Uno没有原生3.3V稳压输出能力较强,建议加装AMS1117-3.3V模块单独供电。
软件实现:从零跑通第一个程序
现在我们来写一段能让屏幕亮起来的最小可运行代码。
第一步:安装必要库
打开Arduino IDE → 工具 → 管理库 → 搜索并安装:
Adafruit GFX LibraryAdafruit ST7789
这两个库构成了Arduino生态中最稳定的TFT绘图基础。
第二步:编写初始化代码
#include <SPI.h> #include <Adafruit_GFX.h> #include <Adafruit_ST7789.h> // 定义引脚 #define TFT_CS 5 #define TFT_DC 2 #define TFT_RST 4 // 创建对象 Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST); void setup() { Serial.begin(115200); delay(100); // 初始化屏幕 tft.init(240, 240); // 分辨率 tft.setRotation(1); // 横屏显示 tft.fillScreen(ST7789_BLACK); // 清屏 // 测试文字 tft.setCursor(20, 50); tft.setTextColor(ST7789_WHITE); tft.setTextSize(2); tft.println("Hello World!"); // 画个圆 tft.drawCircle(120, 120, 50, ST7789_RED); } void loop() { }关键函数解读
| 函数 | 作用 |
|---|---|
init(w, h) | 执行完整的初始化序列,唤醒屏幕 |
setRotation(n) | 设置显示方向(0~3对应四个角度) |
fillScreen(color) | 全屏填充 |
drawXXX() | 各种绘图函数(线、矩形、圆等) |
💡 小技巧:
setRotation(1)通常能得到横向居中的最佳视觉效果。
常见问题排查清单:再也不怕“黑屏恐慌”
即使照着做,也可能遇到问题。以下是高频故障及解决方案:
🟨 问题1:完全无反应,屏幕黑着
- ✅ 检查VCC是否为3.3V(万用表测)
- ✅ 确认GND已连接
- ✅ 查看RST是否悬空(应接GPIO或上拉)
- ✅ 更换杜邦线测试(劣质线常接触不良)
🟨 问题2:白屏或花屏
- ✅ 检查SPI模式是否正确(库一般自动处理)
- ✅ 确保DC引脚连接无误
- ✅ 尝试降低SPI频率:
cpp SPI.setFrequency(20000000); // 改为20MHz试试
🟨 问题3:字体倒置、图像错位
- ✅ 调整
setRotation()参数,尝试0~3 - ✅ 某些模块出厂GRAM映射不同,需查阅规格书
🟨 问题4:颜色发绿或偏蓝
- ✅ 检查是否设置了正确的像素格式(RGB565)
- ✅ 确保未启用BGR模式(有些模块默认是BGR)
可以在初始化后手动设置:
tft.writecommand(ST7789_MADCTL); tft.writedata(0x08); // RGB顺序,非BGR性能优化建议:让动画更流畅
如果你打算做动态界面(如仪表盘、小游戏),以下几点能显著提升体验:
1. 局部刷新代替全屏重绘
// 错误做法:每次清屏再画 tft.fillScreen(BLACK); drawNewFrame(); // 正确做法:只更新变化区域 tft.fillRect(x, y, w, h, BLACK); // 擦除局部 drawNewContent();2. 提高SPI频率(慎用)
SPI.setFrequency(40000000); // 最高40MHz(视线路质量而定)⚠️ 长导线或劣质接线可能导致高频下通信错误。
3. 使用TFT_eSPI库替代Adafruit(进阶)
对于ESP32用户,强烈推荐尝试TFT_eSPI,它提供了:
- 更快的绘制速度
- 支持DMA传输
- 自定义字体压缩
- 触摸屏集成支持
虽然学习成本稍高,但在复杂UI场景下优势明显。
更进一步:你能用它做什么?
掌握了基本驱动之后,真正的创造力才刚刚开始。
✅ 数据可视化仪表盘
结合DHT11传感器,实时显示温湿度曲线:
tft.drawLine(last_x, last_y, current_x, current_y, ST7789_GREEN);✅ 音乐频谱分析器
利用ESP32的I2S接口采集音频,FFT变换后绘制柱状图:
for (int i = 0; i < 16; i++) { tft.fillRect(i*15, 240-height[i], 14, height[i], colors[i]); }✅ 图形化菜单系统
配合按键或电阻触摸屏,实现可点击的按钮、滑块、图标菜单。
✅ 微型掌机
加上摇杆和按键,运行贪吃蛇、俄罗斯方块,甚至移植GB游戏(需优化渲染)。
写在最后:技术成长的起点
一块小小的ST7789屏幕,看似只是“点亮而已”,但它背后涉及的知识体系却很完整:
- 数字通信(SPI)
- 内存管理(GRAM操作)
- 图形绘制算法(线条、填充)
- 硬件协同(电源、时序)
- 调试思维(波形分析、日志追踪)
当你第一次亲手让它显示出清晰的文字和图形时,那种成就感,远超复制粘贴别人的代码。
所以,别再让它躺在抽屉里吃灰了。拿出你的Arduino,接好每一根线,跑通第一段代码——
下一个炫酷的DIY项目,也许就从这一块小彩屏开始。
如果你在实现过程中遇到了其他挑战,欢迎在评论区分享讨论。