跳到主要内容

显示基础与接口

无论驱动哪种类型的屏幕,像素、色深、帧缓冲、显示方向与坐标系这些基础概念都是通用的;而屏幕与主控之间的数据通路(即显示接口)则直接决定了刷新带宽和引脚开销。本章介绍这两部分内容,作为后续各屏幕章节的基础。

1. 显示的公共概念

1.1 像素与分辨率

屏幕上的画面由一个个像素(Pixel)组成。分辨率描述屏幕横向和纵向各有多少个像素,例如 240×320 表示横向 240 个、纵向 320 个像素。驱动屏幕的本质,是为每个像素指定要显示的颜色。

1.2 色深

色深(Color Depth)指每个像素用多少位(bit)来描述颜色,直接决定了一个像素占用的数据量:

色深每像素数据量可表示颜色典型场景
1bpp(单色)1 bit黑 / 白单色 OLED、RLCD、黑白墨水屏
RGB56516 bit(2 字节)65536 色嵌入式彩屏的主流格式
RGB88824 bit(3 字节)约 1677 万色高色彩要求的场景

RGB565 用 5 位表示红色、6 位表示绿色、5 位表示蓝色,在色彩效果和数据量之间取得平衡,是 ESP32 上彩屏开发最常用的格式。

RGB565 的位数分配

嵌入式 LCD 常用 RGB565,是因为一个像素正好占 16 位(2 字节),比 24 位 RGB888 少占三分之一的显存和传输带宽。对 SPI、I80 等接口而言,少传 1 字节通常能直接降低刷新压力,因此很多中小尺寸 LCD 示例和图形库默认使用 RGB565。

绿色分量占 6 位,是因为人眼对绿色亮度变化更敏感,给 G 多分配 1 位可让亮度过渡更细。这样总位数仍保持 16 位,同时把更多层级留给对视觉亮度影响较大的绿色通道。


由“分辨率 × 色深”可以算出一帧完整画面的数据量:

屏幕示例分辨率色深一帧数据量
0.96 英寸单色 OLED128×641bpp1 KB
1.28 英寸圆形 LCD240×240RGB565112.5 KB
2.4 英寸 LCD240×320RGB565150 KB
4.3 英寸 RGB 屏800×480RGB565750 KB

帧数据量直接影响两个关键因素:刷新一帧需要传输多少数据(影响帧率),以及缓存一帧画面需要多少内存(影响内存方案)。

1.3 帧缓冲与显存(GRAM)

屏幕上的画面需要持续维持,因此必须有一块内存保存当前画面的全部像素数据,这块内存称为帧缓冲(Frame Buffer)。它可能位于两个位置:

  • 屏幕侧:多数 SPI / I80 接口的屏幕,其驱动 IC 内部集成了显存(GRAM)。主控把像素数据写入 GRAM 后,驱动 IC 自行负责持续刷新面板。主控无需保存整帧画面,内存压力小,画面不更新时主控无需执行任何操作。
  • 主控侧:RGB 接口的屏幕没有 GRAM,主控必须在自己的内存中维护完整帧缓冲,并按固定时序不间断地向屏幕输出数据。以 800×480 RGB565 为例,一帧就需要 750 KB,远超 ESP32 的片内 RAM,因此驱动 RGB 屏的开发板都需要配备 PSRAM。

这是选择接口时最核心的区别之一:SPI 屏对主控内存要求低,RGB 屏必须有 PSRAM

1.4 刷新与画面撕裂

屏幕并不会在写入后立即显示对应内容,驱动 IC 会按固定的刷新率(如 60 Hz)周期性地把显存内容扫描到面板上。如果主控写入 GRAM 的过程恰好跨越了一次扫描,屏幕上就会同时出现新旧两帧的内容,称为画面撕裂(Tearing)。

部分屏幕引出了 TE(Tearing Effect)引脚,在每次扫描开始时输出一个同步脉冲。主控可以等待该信号后再写入数据,从而避开扫描过程、消除撕裂。静态画面或低速刷新的应用一般无需处理撕裂问题。

有关撕裂的更多讲解,请参考 ESP-IoT-Solution 编程指南 - LCD 屏幕撕裂详解

1.5 全屏刷新与窗口刷新

带 GRAM 的屏幕支持窗口寻址(Window Addressing):先通过命令指定一个矩形区域,之后写入的像素数据只落在该区域内。因此更新画面时不必重传整帧,只刷新变化的部分即可,这能显著降低传输量。LVGL 等图形库的“局部刷新”就是基于这一机制实现的。

信息

墨水屏的“局刷”是另一个概念,它涉及电泳粒子的驱动波形,详见 E-Paper 章节

1.6 显示方向与坐标系

屏幕的原生方向由面板和驱动 IC 的行列排列决定。以原生宽度为 W、高度为 H 的屏幕为例,通常将左上角定义为坐标原点 (0, 0),X 轴向右递增,Y 轴向下递增。模组安装到设备后,屏幕的物理方向可能与原生方向不同,因此需要将显示内容旋转到对应方向。

显示方向改变后,图形库使用的逻辑坐标系也会随之改变。以原生画面顺时针旋转为例,原坐标 (x, y) 与旋转后坐标的关系如下:

顺时针旋转角度逻辑宽度 × 高度原坐标映射到旋转后坐标
W × H(x, y)
90°H × W(H - 1 - y, x)
180°W × H(W - 1 - x, H - 1 - y)
270°H × W(y, W - 1 - x)

实际开发时通常不需要手动计算这些坐标,屏幕驱动或图形库会提供显示方向设置。按照像素转换发生的位置,旋转可分为两种方式:

旋转方式实现原理特点
控制器侧旋转(通常称为硬件旋转)带 GRAM 的驱动 IC 通过行列交换和轴向翻转改变像素寻址方向,部分驱动 IC 使用 MADCTL 等寄存器控制使用驱动 IC 自身的寻址能力,主控无需重排整帧像素,也不需要增加完整的旋转缓冲区;可用方向取决于驱动 IC
主控侧软件旋转CPU、软件画布或 GUI 框架先转换帧缓冲区,再将转换后的像素写入屏幕不依赖驱动 IC 提供完整的旋转能力,但会增加内存占用、数据复制量和计算开销

对于 0°、90°、180°、270° 旋转,如果驱动 IC 支持所需方向,应优先使用控制器侧旋转。它直接使用屏幕控制器的寻址功能,配置完成后仍可按旋转后的逻辑坐标绘图。驱动 IC 不支持行列交换,或者应用需要其他角度和图像变换时,再使用主控侧软件旋转。

Arduino_GFX 的 setRotation()、u8g2 构造器中的 U8G2_R0U8G2_R3 等接口用于设置显示方向。设置后,图形库会按照目标方向调整逻辑坐标和宽高;像素最终由驱动 IC 重新寻址,还是在主控侧完成转换,取决于具体驱动和缓冲方式。

旋转参数以库和驱动定义为准

不同图形库对旋转编号和起始方向的定义不完全相同,部分驱动 IC 也只支持轴向翻转,不能完成 90° / 270° 的行列交换。设置方向前,应查阅所用图形库和驱动的说明;设置后,应读取图形库提供的逻辑宽度和高度,并检查四角的图形是否完整。自行编写驱动时,还需确认不同方向下的窗口寻址偏移。

触摸 IC 通常仍按触摸面板的原生方向输出坐标。显示方向改变后,触摸坐标需要执行相同的轴交换和镜像变换,否则触点位置会与画面错位。具体处理方法见 触摸控制的“坐标与显示的对齐”章节

2. 显示接口对比

屏幕与主控之间常见的接口如下表,核心差异在于数据线数量(决定带宽和引脚开销)以及屏端是否带 GRAM(决定主控内存需求):

接口数据线典型带宽屏端 GRAM典型应用
I2C1(双向)≤ 1 Mbps0.96 英寸等小尺寸单色 OLED
SPI(4 线)140~80 Mbps3.5 英寸以下彩屏、墨水屏、RLCD
QSPI4SPI 的 4 倍1~2 英寸高分辨率 AMOLED
I80(8080 并口)8 / 16较高中小尺寸 LCD
RGB 并口16 / 18 / 243.5~7 英寸大屏
MIPI-DSI1~2 对差分线很高可有可无高分辨率屏(ESP32-P4)

2.1 SPI:最常用的接口

SPI 是 ESP32 上最常见的屏幕接口,引脚少、接线简单,几乎所有系列的 ESP32 都支持。典型的 4 线 SPI 屏幕模块引脚如下(与微雪屏幕模块的丝印对应):

引脚说明
VCC / GND电源
DIN(MOSI)数据线,主控 → 屏幕
CLK(SCLK)时钟线
CS片选,低电平有效
DC命令 / 数据选择:低电平表示发送命令,高电平表示发送像素数据
RST复位,低电平有效。部分模块通过上拉电阻将其固定为高电平,此时无需占用 GPIO,驱动代码中复位引脚参数填 -1
BL背光控制(LCD 特有,可接 PWM 调节亮度)

其中 DC 引脚是显示 SPI 相较普通 SPI 多出的关键信号:屏幕驱动 IC 通过该引脚的电平,区分收到的字节是命令还是数据。

2.2 帧率的三个环节

日常所说的“帧率”实际包含三个相互独立的环节,画面的实际流畅度由三者中的最小值决定:

  1. 渲染帧率:主控生成图像数据的速率。取决于主控性能与画面复杂度(局部更新通常快于全屏更新),是动态变化的。

  2. 接口帧率:图像数据经显示接口传输到驱动 IC 的速率。由接口带宽与一帧数据量决定,初始化后基本固定:

    接口帧率上限 ≈ 接口带宽 ÷ 一帧数据量
  3. 屏幕刷新率:驱动 IC 将显存内容扫描到面板的速率(见刷新与画面撕裂)。SPI / I80 屏由驱动 IC 决定(可通过命令配置),RGB 屏则等于接口帧率。

接口帧率是选型时最需要估算的环节。以 40 MHz 的 SPI 驱动 240×320 RGB565 屏幕为例:一帧约 1.23 Mbit,接口帧率上限约为 40 Mbps ÷ 1.23 Mbit ≈ 32 帧/秒(实际还有命令与协议开销,会更低一些)。这一估算可以解释几个常见现象:

  • SPI 驱动 2 英寸级别的屏幕运行 GUI 是流畅的,但驱动更大分辨率则带宽不足。
  • AMOLED 分辨率高(如 410×502、466×466),SPI 带宽不够,所以普遍采用 QSPI。
  • 800×480 这类大屏一帧 750 KB,串行接口均无法达到可用帧率,必须使用 RGB 或 MIPI-DSI 接口。

若接口帧率估算充足而实际画面仍不流畅,瓶颈通常在渲染帧率,应优化绘制逻辑或降低画面复杂度,而非提高接口时钟。

2.3 各接口小结

  • I2C:引脚最少(与其他 I2C 器件共用总线),但带宽最低,只适合小尺寸单色 OLED。
  • SPI:通用性最好的选择,本教程大部分示例基于 SPI 屏幕。
  • QSPI:将 SPI 的 1 根数据线扩展为 4 根,协议相近,带宽提升至 4 倍,是高分辨率 AMOLED 的主流接口。
  • I80:并行传输带宽高于 SPI,但占用 8~16 个 GPIO,在引脚紧张的 ESP32 上使用较少。
  • RGB:主控直接输出面板时序,带宽高、成本低,但占用 GPIO 多且必须整帧缓冲(依赖 PSRAM)。
  • MIPI-DSI:手机屏使用的高速差分接口,引脚少带宽高,目前仅 ESP32-P4 支持。

3. ESP32 的显示接口支持

不同系列的 ESP32 支持的显示接口不同,选屏前需要确认主控能力:

接口支持的 ESP32 系列
I2C / SPI / QSPI全系列(通过通用 I2C / SPI 外设)
I80原生支持:ESP32(I2S 的 LCD 模式)、ESP32-S2、ESP32-S3、ESP32-S31、ESP32-P4(专用 LCD 外设)
模拟支持:ESP32-C5 / C6 / H2 等无原生 I80 外设的型号,可用 Parlio 外设模拟 I80 时序
RGBESP32-S3、ESP32-S31、ESP32-P4
MIPI-DSIESP32-P4

各系列的具体支持情况以 ESP-IoT-Solution:LCD 开发指南 - 支持的接口类型 为准。

其中 ESP32-P4 接口最完整,是高分辨率屏幕的首选;ESP32-S3 凭借专用 LCD 外设和可选的大容量 PSRAM,是目前带屏应用最常用的型号;新推出的 ESP32-S31 支持的接口类型与 ESP32-S3 相同,RGB 屏的实测帧率更高;ESP32-C3 / C6 等主要使用通用 SPI,适合搭配中小尺寸 SPI 屏。

在 Arduino 生态中,上述接口差异大多已由图形驱动库封装,常用的库有:

适用范围
GFX Library for Arduino(Arduino_GFX)彩屏通用图形库,支持 SPI / QSPI / I80 / RGB 多种总线与大量驱动 IC
LovyanGFX彩屏图形库,性能优秀,支持触摸与多种总线
TFT_eSPI经典 SPI 彩屏图形库,通过配置文件适配屏幕
u8g2单色屏图形库,OLED / RLCD 常用,字体资源丰富
GxEPD2墨水屏驱动库
微雪示例程序包各开发板 / 屏幕模块的官方驱动与示例,引脚和参数已适配好

各类屏幕分别适合用哪个库,在对应章节和 GUI 框架 章节中具体介绍。

提示

使用微雪的带屏开发板(如 ESP32-S3-Touch-LCD 系列)时,屏幕已直连主控,无需接线;官方示例程序包中的引脚定义和初始化参数可直接使用。

4. 驱动一块屏幕的通用流程

各类屏幕与接口的驱动流程基本一致,理解该流程有助于阅读后续章节的示例代码:

  1. 初始化总线:配置 SPI / I2C 等接口的引脚和时钟频率。
  2. 复位屏幕:拉低 RST 引脚一段时间后释放,使驱动 IC 回到确定状态。
  3. 发送初始化序列:向驱动 IC 写入一串配置命令,设置电源、扫描方向、像素格式等。这串命令由屏厂针对具体面板调校,一般直接使用微雪示例或驱动库中现成的初始化代码,无需自己编写。
  4. 设置写入窗口:指定接下来要更新的矩形区域(全屏或局部)。
  5. 写入像素数据:按选定的像素格式(如 RGB565)连续写入该区域的像素,画面随之显示。

后续更新画面就是重复第 4、5 步。使用 Arduino_GFX、u8g2 这类库时,第 1~3 步由库的 begin() 完成,第 4、5 步则被封装为 drawPixel()fillRect()drawBitmap() 等绘图 API,但库底层执行的仍是上述五个步骤。

5. 延伸阅读


了解这些公共概念后,即可进入具体屏幕类型的章节。若尚未确定屏幕类型,可回到 显示屏总览 查看选型对比。