SPI 彩屏驱动(ST7789/ILI9734 同款):初始化命令、DC 引脚与显存刷新
更新时间:2026-09-19。前置:SPI 主机 CPOL/CPHA、PinMux。屏是「SPI 传命令/数据 + 额外控制脚」的典型从设备。
本文要回答的问题
- 一块 TFT 除了 SCLK/MOSI/CS 还要哪些脚(DC/RESET/BL),DC 决定什么?
- 上电后那条长长的初始化命令序列在配置什么?
- 怎么设定一个像素窗口并把像素写进显存(GRAM)?
- RGB565 字节序、MADCTL 旋转、刷新速率有哪些坑?
一、接口信号
| 引脚 | 作用 |
|---|---|
| SCL/SCLK | SPI 时钟(多数屏 mode0:CPOL=0,CPHA=0) |
| SDA/MOSI | 主机→屏(多数小屏只写,无 MISO) |
| CS# | 片选 |
| DC(D/C# / A0) | 0=命令(command),1=参数/数据(data),决定当前字节含义 |
| RESET# | 硬复位 |
| BL/LED | 背光使能(常经 MOS 管/PWM 调光) |
| (部分)TE | 撕裂效应信号,可做同步 |
DC 是关键:同一条 SPI 字节,DC=0 时屏解释为命令码(如 2Ah),DC=1 时为该命令的参数或像素数据。驱动要在传输命令字节前把 DC 拉低,发参数/像素前拉高。
二、上电与初始化顺序
1. 上电,RESET# 保持低满足 tRL,再拉高,等休眠退出时间(120ms)
2. SWRESET (01h),等 ~120ms
3. SLEEP OUT (11h),等 5/120ms(内部电源/振荡器稳定)
4. 一串配置命令:
- MADCTL (36h):内存访问控制——旋转/镜像/RGB-BGR 顺序
- COLMOD (3Ah):接口像素格式,0x55=16bit RGB565 / 0x66=18bit
- PORCTRL/PWCTRL/VRHVDV/GCTRL/LCM/VDVVRHEN(电源/电压/伽马,各厂不同)
- 帧率 FRCTR2、伽马校正 GAMMA* 等
5. DISPON (29h) 开显示,开背光 BL这些电源/GAMMA 参数必须照该具体型号 datasheet/例程,不同厂、不同玻璃(ST7789/ILI9341/GC9A01)序列不同,乱抄会花屏或不亮。ST7789 多为 240×240/240×320,ILI9341 多 240×320。
三、设置窗口 + 写显存
写任意区域:
CASET (2Ah):列起始 SC(2B)、列结束 EC(2B) // x 范围
RASET (2Bh):行起始 SP(2B)、行结束 EP(2B) // y 范围
RAMWR (2Ch):随后所有像素数据连续写入 GRAM(自动在窗口内换行)
每像素 16bit RGB565:RRRRR GGGGGG BBBBB(高字节先发)
写满 (EC-SC+1)*(EP-SP+1) 个像素后自动停/可继续控制器内部维护自增地址指针,在窗口内从左到右、从上到下。整屏刷新就是把窗口设成全屏再发 width×height×2 字节;局部刷新只设小窗口,省带宽。
四、RGB565 与字节序
- 16 位:高 5 红、中 6 绿、低 5 蓝。像素
(r5,g6,b5):(r<<11)|(g<<5)|b。 - SPI 先发高字节;若 MCU 是小端内存里存 16 位,直接 DMA 会先发低字节,需要字节交换或把显存按发送序排列,否则红蓝/高低位错乱(颜色怪、图像错位)。
- MADCTL 的 BGR/RGB 位决定屏内 RGB 排列,和接口字节序是两件事,配错会红蓝互换。
- 部分控制器/接口支持 18bit(用 3 字节),COLMOD 必须与实际发送一致。
五、带宽与刷新架构
SPI 全屏数据量:240×320×2=153,600 字节,62.5MHz 单线下约 20+ms/帧(理论),实际受命令/间隔限制约 30–40fps 量级。优化:
- 局部刷新:只重画变化矩形(UI 控件、字符块)。
- DMA + SPI FIFO:CPU 填显存改为 DMA 搬运,配合 TE 信号在消隐期写,避免撕裂。
- 帧缓冲取舍:小 MCU 常无整屏 RAM,按需直接画;有 PSRAM/SRAM 可开整帧缓冲做双缓冲(见 AXI-Stream/DMA)。
- 想更快用 8/9/16 位并行(8080)或 Quad-SPI/DSI 接口。
六、常见的坑
- DC 时序错:命令字节期间 DC 没拉低,或数据没拉高,屏收到全是错命令。
- 忘退出睡眠/等待时间不足:发了 11h/01h 立刻写数据,电源未稳导致花屏;要够 t。
- COLMOD 与实际位深不符:设 16 位却发 18 位数据,整屏斜切错位。
- RGB565 字节序/小端:DMA 直接发 16 位帧缓冲导致高低字节反,颜色/像素错位。
- MADCTL 旋转/BGR 错:画面旋转镜像或红蓝对调。
- 窗口坐标算错:CASET/RASET 起/止反或含 240 屏的偏移(offset,部分 240×240 玻璃显存是 240×320,有 X/Y offset),图像偏移。
- CS 没在命令-数据间处理对:一条命令+多参数必须保持 CS 连续,中途松开参数丢失。
- SPI 模式/速率:个别屏需 mode3;上电初期低速、稳定后才提速。
- 电源/Gamma 参数乱抄:不同玻璃序列不通用,花屏/颜色失真/白屏。
- 背光直拉 IO:LED 电流大,需 MOS 管/PWM,直接驱动伤引脚。
- 整屏同步写撕裂:不在 TE/消隐期更新,画面撕裂。
- RESET 与上电时序错:电压未稳释放复位导致初始化失败。
相关与延伸
SPI 位级时序见 SPI CPOL/CPHA;控制脚配置见 PinMux;高速搬运见 AXI4-Stream 与 DMA;背光调光见 PWM。
总结
SPI TFT 用 DC 脚区分同一字节流里的命令(DC=0)和参数/像素数据(DC=1):上电要按「硬复位→SWRESET→SLEEP OUT 并等足电源稳定时间→配 MADCTL/COLMOD/电源/Gamma(必须对具体玻璃)→DISPON 开背光」的顺序初始化,画图则用 CASET/RASET 设矩形窗口、RAMWR 后连续发每像素 2 字节的 RGB565(SPI 先发高字节,小端 DMA 要交换,MADCTL 的 BGR 另管红蓝排列);用局部刷新+DMA+TE 同步提升帧率防撕裂——DC 时序、睡眠等待、位深不符和字节序是四大高发坑。