资讯动态

ESP32-S3驱动ST7789P3屏幕:SPI接口初始化命令全解析

发布时间:2026/8/30 4:30:42 来源:尧图企业网站定制
这次我们来看一块非常常见、但经常把人卡在“白屏”或“花屏”上的屏ST7789P3。这类驱动 IC 大量出现在 1.86 寸 IPS LCD 模组上尤其是 ESP32-S3 开发板的配套屏幕里。很多朋友把 SPI 线接好代码也编译通过了结果屏幕要么全白、要么颜色发紫、要么上下颠倒最终问题基本都出在初始化命令序列上。这篇文章不绕弯子直接讲清楚两件事ST7789P3 通过 SPI 接口时哪些命令是必发的这些命令到底在干什么在 ESP-IDF 框架下怎么用 C 语言和 FreeRTOS 把这套流程跑起来并提供一个便于排查的思路。如果你正在做 ESP32-S3 嵌入式 AI 物联网项目后续打算把模型推理结果、传感器数据、调试日志显示在 1.86 寸屏上那建议把这篇收藏。SPI 驱动 ST7789P3 的命令规范是芯片级通用的不只是 ESP32-S3 能用STM32、树莓派 Pico、Arduino 接同一块屏时命令序列也是一套。1. 核心能力速览先把 ST7789P3 ESP32-S3 这套组合的关键信息列出来方便判断这个方案是否适合你。能力项说明驱动芯片ST7789P3ST7789 系列衍生型号命令与 ST7789V 高度兼容接口方式4 线 SPISCLK / MOSI / CS / DC另有 RES 复位和 BLK 背光常见分辨率240x320、240x280具体以模组规格书为准像素格式RGB565、RGB666最常用 RGB565驱动框架ESP-IDF v5.x 的 esp_lcd 组件或手写 SPI Master FreeRTOS核心命令数量基础必发约 10 条厂商调优命令按规格书补充支持平台ESP32-S3 / ESP32 / STM32 等任意 SPI 主机API 服务本文不涉及 HTTP/网络 API但 SPI 驱动本身支持批量事务批量刷新支持按矩形窗口刷新、分块刷新、双缓冲预留适用场景桌面看板、AI 推理结果展示、传感器数据可视化、无线调试器本地显示这块屏的核心价值不是性能有多强而是“小巧 接口简单 资料多”。ESP32-S3 的 SPI 外设跑到 20MHz 或 40MHz 驱动 240x320 的 RGB565 屏幕足够日常显示。关键是要把命令顺序发对否则性能再好也是白屏。2. 适用场景与使用边界ST7789P3 适合谁先说结论适合需要一块小型彩色屏但不想引入太复杂硬件设计的项目。典型场景有这几类ESP32-S3 嵌入式 AI 物联网项目显示识别结果、模型置信度、推理耗时、传感器曲线比串口日志直观得多。无线 AI 调试器通过 WiFi 接收上位机或另一块开发板发来的调试数据实时在屏幕上显示状态。桌面小工具时钟、天气、歌词显示、系统监控面板。学习 ST7789 命令时序和 ESP-IDF SPI 驱动原理的实验板。需要注意使用边界ST7789P3 不是大屏1.86 寸显示信息量有限不要指望它做复杂的数据可视化。屏幕刷新需要占用 SPI 总线如果 SPI 总线上还挂了 SD 卡、Flash 等其他设备要注意总线占用和冲突。实时性要求很高的动画场景需要考虑一帧刷新耗时。20MHz 下 240x320 全屏 RGB565 的理论传输时间约 61ms实际帧率会低于理论值。涉及图像显示时注意素材版权。显示人物照片、品牌 Logo、受版权保护的图片要确认授权。本地开发和测试场景尽量使用自绘或无版权素材。另外如果你的项目要接入 WiFi、BLE 或 AI 推理屏幕驱动只是其中一个模块。建议把显示任务和业务任务用 FreeRTOS 解耦避免屏幕刷屏卡住主流程。3. SPI 接口与接线准备先看硬件连接。ST7789P3 模组通常引出 7 到 9 个引脚其中与 SPI 相关的核心引脚如下。信号方向作用接线说明SCLK / SCK输入SPI 时钟接 ESP32-S3 SPI 时钟脚MOSI / SDA输入SPI 数据接 ESP32-S3 MOSI屏幕只写不读时 MISO 可不接CS输入片选低电平有效DC输入命令/数据选择低电平发命令高电平发数据RES / RST输入硬件复位低电平复位需外部拉高或由 MCU 控制BLK / LEDA输入背光控制接 GPIO 高电平点亮或接 PWM 调光接线时注意三个点第一DC 脚不能省。ST7789P3 的 SPI 是“命令/数据共线”靠 DC 电平区分传输类型。某些模组设计成 3 线 SPI也就是把命令和数据通过 9 bit SPI 封装区分那种情况不需要 DC 脚但本文以最常见的 4 线 SPI 为例。第二CS 可以用硬件片选。ESP-IDF 的 SPI 主机支持硬件 CS给spi_device_interface_config_t配置spics_io_num即可不需要手动拉 CS。但 DC 必须由 GPIO 手动控制因为它在每次传输前要区分命令和数据。第三背光脚必须处理。很多模组默认背光亮但有些模组需要外部拉高。如果代码全部初始化正确但屏幕是黑的先检查 BLK 是否处于有效电平。下面是一组通用接线参考实际引脚按你自己的开发板调整#define PIN_SCLK GPIO_NUM_12 #define PIN_MOSI GPIO_NUM_11 #define PIN_DC GPIO_NUM_10 #define PIN_CS GPIO_NUM_9 #define PIN_RST GPIO_NUM_8 #define PIN_BL GPIO_NUM_7这组引脚不是标准答案只是常见参考。实战派一类的 ESP32-S3 开发板屏幕引脚一般会印在 PCB 上或者查原理图确认。4. ST7789P3 常用命令拆解这是本文的重头戏。ST7789P3 和 ST7789V 一样是一颗 MIPI DCS 兼容的显示驱动 IC。命令本身不复杂但顺序错了就会白屏或花屏。下面按初始化流程逐个拆。4.1 软件复位 SWRESET0x01开机后建议先发软件复位。虽然硬件 RES 引脚也能复位但软件复位更保险尤其在代码启动时序不稳定的情况下。发送方式CMD(0x01);复位后需要延时。一般延时 120ms 是比较稳妥的做法。紧跟着应发送退出睡眠命令。4.2 退出睡眠 SLPOUT0x11ST7789P3 上电后默认处于睡眠模式此时屏幕不显示内容。SLPOUT是初始化中最重要的命令之一如果漏掉屏幕就会一直黑着。CMD(0x11); // SLPOUT vTaskDelay(pdMS_TO_TICKS(120));这个命令之后必须给足够延时。数据手册通常要求 120ms 左右工程上直接延时 120ms 即可。延时不够容易导致后续命令没被正确执行表现就是偶尔白屏或显示异常。4.3 像素格式 COLMOD0x3AST7789P3 支持多种颜色深度。最常用的是 RGB565也就是 16 位色色彩信息压缩到每像素 2 字节。CMD(0x3A); lcd_write_data(0x55); // RGB565参数说明参数值含义0x5516 位 / 像素RGB565最常用0x6618 位 / 像素RGB666颜色更准但传输量更大0x7724 位 / 像素传输量最大不推荐在 ESP32 上使用ESP32-S3 的 SPI 外设可以直接送 16 位像素流。如果选了 18 位单个像素需要 3 字节刷新速度和帧缓冲占用都会增加。一般项目用 0x55 足够。4.4 内存访问控制 MADCTL0x36MADCTL 是另一个容易翻车的命令。它控制显示方向、RGB/BGR 顺序、行列镜像。CMD(0x36); lcd_write_data(0x00);MADCTL 的 8 个 bit 含义如下Bit符号作用7MY行方向翻转6MX列方向翻转5MV行列交换旋转 90 度4ML垂直刷新方向3BGR1 为 BGR0 为 RGB2MH水平刷新方向1-0-保留实际使用时常见的几个值0x00竖屏RGB 顺序通常配合 240x320 面板。0x60即 MX MV常用于横屏配合 320x240 使用。0xA0即 MY MV另一种横屏方向。0xC0即 MX MY相当于原始方向旋转 180 度。0x08在 0x00 基础上换成 BGR 顺序。屏幕显示方向没有绝对正确因为模组绑定到开发板时排线方向可能不同。调试时先把 MADCTL 设为 0x00画一个矩形如果上下颠倒就加 MY左右颠倒就加 MX横竖颠倒就加 MV。颜色不对就切换 bit3。4.5 反色控制 INVON / INVOFF0x21 / 0x20ST7789P3 的内存数据和实际显示颜色之间有一个可选的反色开关。同一个命令序列在不同模组上显示效果可能正好相反有的模组需要INVON有的需要INVOFF。CMD(0x21); // INVON如果颜色发傻试试 0x20判断方法很简单先按 0x21 发如果显示白色背景但看起来是黑色、或者颜色明显异常就把命令改成 0x20。ST7789 系列屏幕常见的“红色变蓝色”“白色变黑色”一半原因是 BGR 位错了另一半就是反色命令反了。4.6 列地址设置 CASET0x2ACASET 用于设置刷屏区域的列范围。发送 4 字节参数依次是 X 起始高字节、X 起始低字节、X 结束高字节、X 结束低字节。以 240x320 全屏为例CMD(0x2A); uint8_t caset[] {0x00, 0x00, 0x00, 0xEF}; // X: 0 到 239 lcd_write_data_bytes(caset, 4);4.7 行地址设置 RASET0x2BRASET 和 CASET 类似设置行范围。同样是 4 字节参数。CMD(0x2B); uint8_t raset[] {0x00, 0x00, 0x01, 0x3F}; // Y: 0 到 319 lcd_write_data_bytes(raset, 4);有的模组在上电后并不从 0 开始显示而是在左上角存在偏移比如某些 1.86 寸屏幕需要把起始地址偏置 20 或 40 像素。遇到“全屏内容错位、画面整体向右下方偏移”的情况需要根据模组规格书在 CASET/RASET 基础上加偏移量。4.8 写显存 RAMWR0x2C地址窗口设好后发送RAMWR接下来所有 SPI 数据都会被写入 GRAM。写入顺序从地址窗口左上角开始按行从左到右、从上到下连续写入。CMD(0x2C);之后设置 DC 为高电平连续发送 RGB565 像素数据即可。数据字节序通常是高字节在前也就是颜色0xF800先发0xF8再发0x00。如果颜色看起来每个像素都被拆成两半大概率是字节序问题。4.9 读显存 RAMRD0x2ERAMRD读取 GRAM 内容一般用于屏幕截图或回读校验。但很多模组没有把 MISO 接到 MCU 上这种模组就用不了读命令。如果 SPI 总线只接了 MOSI直接跳过这条命令。4.10 正常显示模式 NORON0x13初始化时发送NORON让屏幕进入正常显示模式。这个命令一般放在睡眠退出之后、显示开启之前。CMD(0x13);有些初始化序列还会在0x13之前发送0x12PON 部分显示模式或者0x14反色部分模式但工程上常规流程不需要。4.11 显示开启 DISPON0x29最后一条必发命令是DISPON。发送后屏幕真正开始显示内容。CMD(0x29); vTaskDelay(pdMS_TO_TICKS(20));4.12 撕裂效果控制 TE0x350x35开启撕裂效果信号。如果使用 GPIO 监视 TE 引脚可以在刷新前等待垂直同步避免画面撕裂。没有 TE 引脚时跳过即可。4.13 厂商调优命令ST7789P3 的数据手册里还有一组厂商命令比如电源控制、栅极控制、Gamma 校正等命令功能0xB2Porch 控制0xB7栅极控制0xBBVCOM 设置0xC0LCM 控制0xC2VDV 与 VRH 命令相等设置0xC3VRH 设置0xC4VDV 设置0xC6帧率控制0xD0电源控制 10xE0 / 0xE1正负 Gamma 校正这组命令的值通常由模组厂出厂时确定。很多开源屏幕驱动会直接内置一组 ST7789V 的通用值但不同模组之间存在差异盲目照抄可能对比度偏低或偏色。最稳妥的做法是找你的模组规格书把电源和 Gamma 部分按 PDF 里的推荐值填进去。如果只是做基础显示前 11 条命令已经足够点亮屏幕。5. ESP32-S3 本地部署环境准备接下来说代码侧。推荐使用 ESP-IDF v5.x 版本原因很简单v5.x 内置esp_lcd组件ST7789 面板驱动开箱即用不需要手写复杂命令序列。安装和初始化 ESP-IDF 的基本流程如下# 选择你要使用的 IDF 分支例如 v5.2 git clone -b v5.2 --recursive https://github.com/espressif/esp-idf.git # 进入 IDF 目录运行安装脚本Linux / macOS ./install.sh esp32s3 # 导出环境变量 source export.shWindows 用户可以直接使用 Espressif 官方提供的 IDF Tools 安装器图形界面选择 ESP32-S3 工具链。创建工程后先设置目标芯片idf.py set-target esp32s3编译和烧录

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价