2026/1/11 5:05:50
网站建设
项目流程
西安网站建设服务,电子商务网站建设目标分析,自己主机做网站服务器吗,怎么开发自己的直播app从零点亮一块彩屏#xff1a;手把手教你用SPI驱动ST7789显示屏你有没有想过#xff0c;自己亲手让一块小小的彩色屏幕亮起来#xff0c;显示文字、图形甚至动画#xff1f;听起来像是高手才玩得转的事#xff0c;但其实只要掌握正确的方法#xff0c;哪怕你是嵌入式开发的…从零点亮一块彩屏手把手教你用SPI驱动ST7789显示屏你有没有想过自己亲手让一块小小的彩色屏幕亮起来显示文字、图形甚至动画听起来像是高手才玩得转的事但其实只要掌握正确的方法哪怕你是嵌入式开发的“小白”也能在几小时内完成这个看似高深的操作。今天我们要聊的是ST7789—— 一块在1.3英寸到2.0英寸小屏幕上几乎无处不在的TFT控制器芯片。它被广泛用于智能手表、便携仪表、DIY项目中而最常用、也最适合初学者上手的方式就是通过SPI接口来控制它。别担心没基础。这篇文章不堆术语、不甩理论只讲你能看懂、能动手、能成功的实战路径。我们会从接线开始一步步走到屏幕全亮、刷出颜色最后告诉你怎么避免那些让人抓狂的“黑屏”、“花屏”坑。为什么是 ST7789又为什么选 SPI先说个现实现在做嵌入式项目谁还愿意为一个屏幕拉十几根线搞并口通信MCU引脚宝贵得很尤其是像ESP32-Sx系列或者STM32G0这类资源紧张的芯片省一根是一根。ST7789 的好处就在于——功能强还省事。它支持最高 240×320 分辨率原生支持 RGB565 色彩格式也就是常说的16位色约6.5万色内置升压电路和伽马校正最关键的是它可以用四根线就跑起来SCK、MOSI、CS、DC。加上 RST 和电源总共也就七八个引脚搞定。而这四根核心信号线走的就是SPI 协议。SPI 是什么你可以把它想象成一种“对讲机式”的通信方式主控比如你的单片机说话屏幕听着不需要回话因为大多数时候我们只写不读。简单、高效、通用性强。更重要的是几乎所有主流开发平台都原生支持 SPI- Arduino 有SPI.h- ESP32 支持硬件 SPI DMA 加速- 树莓派 PicoRP2040用 C/C SDK 轻松配置- STM32 HAL 库直接调用传输函数所以选择 ST7789 SPI 组合等于选择了低成本、低门槛、高兼容性的入门方案。接线很简单但每根线都有讲究先来看一张最基础的连接图MCU 引脚→ST7789 模块GPIOx (SCK)→SCK / CLKGPIOy (MOSI)→MOSI / DINGPIOz (CS)→CS / SSGPIOa (DC)→DC / A0GPIOb (RST)→RST3.3V→VCCGND→GND可选PWM→BLK / LED_K⚠️ 注意有些模块标的是 VIN 而不是 VCC其实是同一个意思BLK 是背光控制脚接 PWM 可调亮度。这里面最容易忽略的细节是电平匹配。虽然 ST7789 支持 1.8V~3.3V IO 电压但如果你用的是 5V 系统比如老款 Arduino Uno必须加电平转换器或串电阻限流否则可能烧毁模块另外RST 引脚不能省。虽然有些代码里看到“不用硬件复位”但强烈建议接上。很多初始化失败的问题根源就是芯片没真正重启。SPI 模式怎么选Mode 0 还是 Mode 3这是新手最容易栽的第一个坑。SPI 有四种工作模式由两个参数决定CPOL时钟极性和 CPHA时钟相位。ST7789 官方文档写着支持 Mode 0 和 Mode 3那到底该用哪个答案是优先试 Mode 0CPOL0, CPHA0什么意思- 空闲时 SCK 为低电平- 数据在上升沿采样即每个时钟周期的后半段稳定这几乎是市面上绝大多数开发板默认的设置。你在 Arduino 或 STM32CubeMX 中启用 SPI 外设时默认就是这个模式。如果 Mode 0 不行再尝试切换到 Mode 3CPOL1, CPHA1试试。有时候某些厂商改了内部逻辑会要求空闲高电平。✅ 实战提示可以用示波器抓一下 SCK 波形看看是否符合预期没有设备的话就靠换代码配置多试几次。命令与数据交替传输ST7789 的“语言规则”理解这一点你就掌握了和屏幕“对话”的钥匙。ST7789 并不像普通外设那样收发固定协议的数据包它是靠命令 参数的方式工作的。就像点菜一样- 先告诉它你要干嘛下命令- 再把具体信息传过去送参数而区分“命令”和“数据”的关键就是那根叫DC的引脚。DC 状态含义DC 0当前传输的是命令字节例如0x2A表示设置列地址DC 1当前传输的是数据参数或像素值举个例子你想设置显示区域为左上角 (0,0) 到右下角 (239,319)拉低 CS → 发送 0x2A (DC0) → 发起始高位 (DC1) → 起始低位 → 结束高位 → 结束低位 → CS 拉高整个过程如下void ST7789_WriteCmd(uint8_t cmd) { CS_LOW; DC_LOW; // 命令模式 spi_write(cmd, 1); DC_HIGH; // 自动切回数据模式方便后续连续写数据 } void ST7789_WriteData(uint8_t *buf, size_t len) { CS_LOW; spi_write(buf, len); // 此时 DC 已为高表示数据 CS_HIGH; }注意看我们在发送完命令后立刻把 DC 拉高——这是一个小技巧因为接下来大概率要写参数提前准备好状态可以减少一次 GPIO 切换提升效率。初始化序列让屏幕“醒过来”的魔法咒语刚上电的 ST7789 是沉睡的。它需要一系列特定的命令才能进入正常工作状态。这些命令组合起来叫做初始化序列Initialization Sequence。你可以把它理解为“开机自检系统配置”。下面是典型的一段初始化流程适用于大多数 240x320 屏void ST7789_Init(void) { // 硬件复位 RST_LOW; delay_ms(10); RST_HIGH; delay_ms(150); // 软件复位 ST7789_WriteCmd(0x01); delay_ms(150); // 退出睡眠模式 ST7789_WriteCmd(0x11); delay_ms(200); // 必须等够手册要求 ≥120ms // 设置色彩格式为 16-bit (RGB565) ST7789_WriteCmd(0x3A); ST7789_WriteByte(0x05); // 0x05 16位色 // 设置内存访问方向旋转/镜像 ST7789_WriteCmd(0x36); ST7789_WriteByte(0xC0); // 常见竖屏方向可根据实际调整 // 设置列地址范围0~239 ST7789_WriteCmd(0x2A); uint8_t col_addr[] {0x00, 0x00, 0x00, 0xEF}; // 240列 ST7789_WriteData(col_addr, 4); // 设置行地址范围0~319 ST7789_WriteCmd(0x2B); uint8_t row_addr[] {0x00, 0x00, 0x01, 0x3F}; // 320行 ST7789_WriteData(row_addr, 4); // 开启显示 ST7789_WriteCmd(0x29); }其中最关键的几个点-0x11Sleep Out之后必须延时至少120ms-0x36MADCTL决定了屏幕怎么“躺着”显示常见值有0x00,0x60,0xC0,0xA0分别对应不同旋转角度-0x29Display On才是真正点亮屏幕的开关如果你的屏幕一直黑着先检查是不是漏了0x11或者0x29或者延时不达标。如何画满屏向 GRAM 写入像素数据GRAM 是什么它是 Graphics RAM 的缩写即图形内存。虽然 ST7789 本身没有大容量 RAM 存储整帧图像但它提供了一个“窗口机制”你告诉它一个区域然后往里面不停地写颜色数据它就会自动映射到屏幕上。写像素的核心命令是0x2CWrite Memory Start意思是“接下来所有数据都是像素点了。”比如我们想把整个屏幕刷成白色RGB565 下白色是0xFFFFvoid ST7789_FillScreen(uint16_t color) { ST7789_SetWindow(0, 0, 239, 319); // 设定区域 ST7789_WriteCmd(0x2C); // 开始写显存 uint8_t hi color 8; uint8_t lo color 0xFF; // 构造重复颜色数组建议用DMA或缓冲区优化 for (int i 0; i 240 * 320; i) { ST7789_WriteByte(hi); ST7789_WriteByte(lo); } }当然这种轮询写法非常慢尤其是在 SPI 频率只有 4MHz 的情况下刷一屏可能要几百毫秒。但在调试阶段完全可用。 提升建议使用 DMA 传输、双缓冲机制或将颜色预存在数组中批量发送。屏幕方向怎么调MADCTL 寄存器详解很多人第一次点亮屏幕发现图像是倒的、歪的、镜像的……别慌这很正常。这一切都由MADCTLMemory Access Control寄存器控制地址是0x36。它是一个8位寄存器每一位都有含义Bit名称功能7MY行扫描顺序1从下往上6MX列扫描顺序1从右往左5MVX/Y 是否交换1行列互换实现90度旋转4ML扫描方向1从底到顶逐行3RGB接口颜色顺序1RGB0BGR重要2:0-保留常用组合举例值十六进制效果说明0x00默认横向左上起点0x60旋转90度适合竖屏0xC0旋转180度0xA0旋转270度0x20水平翻转 实战经验如果你发现颜色偏蓝或偏红很可能是 RGB/BGR 搞反了。试试把 bit3 取反。常见问题排查清单那些年我们一起踩过的坑❌ 屏幕完全不亮检查供电是否正常3.3V有无短路RST 是否有效触发可用万用表测复位电平变化是否发送了0x11和0x29缺一不可SPI 是否工作可用示波器看 SCK 是否有波形❌ 显示花屏、错位、条纹CASET和RASET设置的坐标范围是否正确MADCTL 配置是否与物理安装方向一致SPI 速率是否过高面包板上超过 8MHz 就容易出错❌ 颜色不对发绿、发红RGB565 字节顺序是否颠倒试试交换高低字节MADCTL 的 RGB/BGR 位是否正确测试纯色0xF800红0x07E0绿0x001F蓝❌ 刷新太慢卡顿放弃轮询写法改用 DMA 或 SPI 双缓冲减少全屏刷新改为局部更新Partial Update提高 SPI 主频至 10~15MHz需确保线路质量工程级设计建议不只是点亮更要稳定可靠当你不再满足于“能亮”而是要做产品级应用时以下几点值得重视✅ 电源去耦不能省在 VCC 引脚附近加一个0.1μF 陶瓷电容离模块越近越好。最好再并联一个 10μF 钽电容吸收瞬态电流波动。✅ 背光单独控制BLK 引脚通常连接背光LED阴极。若电流较大100mA建议用三极管或MOSFET驱动避免直接由MCU引脚供电。✅ 使用分层架构构建清晰的软件结构底层SPI 读写抽象 │ ├─ 中间层ST7789 控制初始化、窗口设置、旋转等 │ └─ 上层图形库绘制点线圆、文字、UI框架如LVGL这样未来换平台或换屏幕都更容易移植。✅ 区域更新优于全屏刷新对于仅变动一小部分画面的应用如仪表盘指针移动只需重绘变化区域即可大幅降低带宽占用。更进一步结合 GUI 框架打造交互界面一旦你能稳定驱动 ST7789下一步就可以接入轻量级 GUI 框架比如LVGL功能强大支持触摸、动画、主题适合 STM32/ESP32u8g2资源占用极低适合 AVR、nRF 等小内存设备TFT_eSPI Arduino GFXESP32 上最受欢迎的组合之一它们的背后其实都是基于我们刚才讲的这套 SPI 命令-数据模型。你现在打下的基础正是通往更复杂应用的跳板。写在最后每一个高手都曾从点亮第一块屏开始你看整个过程并没有那么神秘。从认识每一根线的作用到理解命令与数据的区别再到写出第一个FillScreen()函数——你已经走完了从“看不懂”到“能做到”的全过程。技术从来不是天才的专利而是坚持实践的结果。也许你现在连 SPI 是什么都还不太清楚但只要动手接一次线、烧录一段代码、看到屏幕真的亮起来那一刻那种成就感足以让你爱上嵌入式开发。如果你正在做一个天气站、音乐播放器、或是带界面的小工具不妨加上这块 ST7789 屏。它不大却能让你的作品瞬间生动起来。如果你在调试过程中遇到问题欢迎留言交流。我们一起解决下一个“黑屏”难题。