3. 驱动芯片选型:ILI9341 / ST7789 / SSD1306 特性对比与数据手册阅读

做 SPI LCD 驱动,第一步不是写代码,而是选芯片。

市面上常见的 SPI 接口驱动芯片,就那么几款。我这些年经手的项目,十有八九是 ILI9341、ST7789 或者 SSD1306。这三款芯片,基本覆盖了从黑白到彩色、从低分辨率到高分辨率的主流场景。

选错了芯片,后面调试会非常痛苦。我见过有人拿着 ST7789 的驱动去点 ILI9341 的屏,折腾了两天画面还是花的。所以,咱们先把这三款芯片的底细摸清楚。

3.1 三款芯片核心参数对比

先看一张对比表。这张表是我自己整理的,项目里经常要翻出来看。

参数项 ILI9341 ST7789 SSD1306
类型 TFT-LCD 彩色 TFT-LCD 彩色 OLED 单色/双色
最大分辨率 320×240 (QVGA) 240×240 / 320×240 128×64 / 128×32
颜色深度 262K / 16.7M 色 262K 色 1 bit (单色)
SPI 模式 Mode 0 / Mode 3 Mode 0 / Mode 3 Mode 0 / Mode 3
最大 SPI 时钟 10~15 MHz 15~20 MHz 10 MHz
内部 RAM 172,800 字节 172,800 字节 1,024 字节
工作电压 2.5V ~ 3.3V 1.65V ~ 3.3V 3.3V ~ 5V
典型应用 2.8寸~3.5寸彩屏 1.3寸~1.8寸小彩屏 0.96寸~1.3寸单色屏

从表里能看出什么?

  • ILI9341 是老大哥,320×240 分辨率,色彩表现好。我最早接触的 2.8 寸屏基本都是它。缺点是功耗偏高,不适合电池供电的小设备。
  • ST7789 是后起之秀,支持 240×240 方形屏,很适合做智能手表、圆形表盘(配合圆形切割)。它的 SPI 时钟能跑到 20 MHz,刷屏速度比 ILI9341 快一截。
  • SSD1306 是单色 OLED,功耗极低。128×64 分辨率,每个像素只有亮或不亮。说白了,它只能显示黑白或黄蓝双色,但胜在简单、省电、便宜。
我的经验: 如果项目对功耗敏感,比如做智能手环、温湿度计,SSD1306 是首选。如果要做彩色 UI,比如菜单、图片显示,ST7789 性价比最高。ILI9341 适合大屏、高画质的场景,比如工控面板。

3.2 数据手册阅读方法

拿到一款新驱动芯片,怎么快速上手?

我个人的习惯是:先看目录,再抓重点。数据手册动辄几百页,从头读到尾不现实。你想想看,我们做驱动开发,最关心的是什么?

  1. 接口时序 —— SPI 怎么配置?Mode 0 还是 Mode 3?
  2. 初始化序列 —— 上电后要发哪些命令?
  3. 显存操作 —— 怎么写像素?怎么设置窗口?
  4. 寄存器列表 —— 关键命令的格式和参数。

下面我以 ILI9341 的数据手册为例,带你走一遍阅读流程。

3.2.1 第一步:找接口时序图

翻到数据手册的 "Interface Timing" 章节。你会看到类似这样的时序图:

// SPI Mode 0 时序要求 (CPOL=0, CPHA=0)
// SCLK 空闲为低,数据在上升沿采样
// 最小 SCLK 周期: 66 ns (约 15 MHz)
// 数据建立时间: 10 ns
// 数据保持时间: 10 ns
// CS 低到 SCLK 上升沿: 15 ns

这里要注意:时序参数一定要看数据手册的 "最小值" 列。我曾经在 STM32F103 上跑 ILI9341,SPI 时钟配到了 18 MHz,结果画面偶尔闪烁。后来查手册发现 ILI9341 最大 SPI 时钟是 15 MHz,降下来就稳定了。

避坑: 不要盲目追求高 SPI 时钟。芯片标称 15 MHz,实际布线长、电平转换、寄生电容都会降速。我一般留 20% 余量,比如标称 15 MHz,实际跑 12 MHz。

3.2.2 第二步:找初始化序列

数据手册里通常有一个 "Initial Setting" 或 "Power On Sequence" 章节。这是驱动开发的核心。

以 ILI9341 为例,典型的初始化流程是:

  1. 硬件复位(RESX 引脚拉低 10 ms,再拉高)
  2. 发命令 0x11 (SLPOUT) —— 退出睡眠模式
  3. 等待 120 ms
  4. 发命令 0x36 (MADCTL) —— 设置 RGB 顺序、扫描方向
  5. 发命令 0x3A (COLMOD) —— 设置像素格式(如 0x55 表示 16 位色)
  6. 发命令 0x29 (DISPON) —— 打开显示

我建议你把初始化序列整理成一张表,方便调试时对照:

步骤 命令 参数 说明
1 0x11 无 退出睡眠模式
2 0x36 0x48 设置 RGB 顺序、扫描方向
3 0x3A 0x55 16 位色 (RGB565)
4 0x29 无 打开显示

3.2.3 第三步:理解显存操作

这是最核心的部分。你要知道怎么往显存里写数据。

ILI9341 和 ST7789 都支持 窗口模式。说白了,就是先设置一个矩形区域,然后连续写像素数据,芯片会自动填充这个区域。

操作流程是:

  • 发命令 0x2A (CASET) —— 设置列起始和结束地址
  • 发命令 0x2B (RASET) —— 设置行起始和结束地址
  • 发命令 0x2C (RAMWR) —— 开始写像素数据

举个例子,你要在 (10, 20) 到 (50, 60) 这个矩形区域画一个红色方块:

// 设置列范围: 10 ~ 50
spi_write_cmd(0x2A);
spi_write_data(0x00);  // 列起始高字节
spi_write_data(0x0A);  // 列起始低字节 (10)
spi_write_data(0x00);  // 列结束高字节
spi_write_data(0x32);  // 列结束低字节 (50)

// 设置行范围: 20 ~ 60
spi_write_cmd(0x2B);
spi_write_data(0x00);  // 行起始高字节
spi_write_data(0x14);  // 行起始低字节 (20)
spi_write_data(0x00);  // 行结束高字节
spi_write_data(0x3C);  // 行结束低字节 (60)

// 开始写像素数据 (RGB565 红色: 0xF800)
spi_write_cmd(0x2C);
for (int i = 0; i < (41 * 41); i++) {
    spi_write_data(0xF8);  // 高字节
    spi_write_data(0x00);  // 低字节
}

这里有个坑:数据手册里地址是包含边界的。比如 CASET 设置 10~50,实际会写 41 列(50 - 10 + 1)。我第一次写的时候忘了加 1,结果画面总是少一行一列。

3.3 三款芯片的差异点

虽然操作思路类似,但细节上各有不同。我挑几个容易踩坑的地方说说。

3.3.1 像素格式

  • ILI9341:支持 12 位、16 位、18 位色。常用 16 位 RGB565,命令 0x3A 参数 0x55。
  • ST7789:同样支持 RGB565,但命令 0x3A 参数 0x05 表示 16 位色。注意,参数值不一样!
  • SSD1306:单色,1 字节表示 8 个像素。写数据时按页(Page)组织,每页 8 行。
关键区别: ILI9341 和 ST7789 的像素格式命令参数不同。如果你把 ILI9341 的初始化代码直接用在 ST7789 上,画面颜色会完全错乱。我踩过这个坑,调了整整一个下午才发现是 0x3A 的参数不对。

3.3.2 扫描方向

命令 0x36 (MADCTL) 控制显示方向。三款芯片的位定义略有差异:

位 ILI9341 ST7789 SSD1306
BIT7 MY (行翻转) MY (行翻转) 无
BIT6 MX (列翻转) MX (列翻转) 无
BIT5 MV (行列交换) MV (行列交换) 无
BIT4 ML (行扫描方向) ML (行扫描方向) 无
BIT3 BGR (RGB/BGR 顺序) RGB (RGB/BGR 顺序) 无

注意 BIT3 的差异:ILI9341 是 BGR 位(1 表示 BGR 顺序),ST7789 是 RGB 位(1 表示 RGB 顺序)。如果你发现画面颜色偏蓝或偏红,多半是这个位没配对。

3.3.3 SSD1306 的特殊性

SSD1306 是 OLED,没有背光,也不需要像素格式设置。它的显存是 1KB,按页组织。128×64 分辨率,分为 8 页,每页 128 字节。

写数据时,要先设置页地址和列地址:

// 设置页地址 (0~7)
spi_write_cmd(0xB0 + page);
// 设置列地址低 4 位
spi_write_cmd(0x00 + (col & 0x0F));
// 设置列地址高 4 位
spi_write_cmd(0x10 + ((col >> 4) & 0x0F));
// 写数据
spi_write_data(byte_data);

这里要注意:SSD1306 的 SPI 通信,命令和数据是靠 D/C 引脚区分的。D/C 为低表示命令,为高表示数据。这个和 ILI9341 是一样的,但 SSD1306 的初始化命令更少,只有十几个。

3.4 如何快速判断芯片型号

拿到一块陌生的屏,怎么知道它用的是什么驱动芯片?

我教你几个土办法:

  • 看丝印:芯片表面通常会印型号,比如 "ILI9341V"、"ST7789V"、"SSD1306Z"。
  • 读 ID:大部分芯片支持读 ID 命令。ILI9341 发 0x04 会返回 3 字节,其中第 2 字节是 0x93。ST7789 发 0x04 返回 0x85。SSD1306 发 0x00 返回 0x3C。
  • 看分辨率:320×240 大概率是 ILI9341,240×240 大概率是 ST7789,128×64 大概率是 SSD1306。
我的习惯: 拿到新屏,先写一个读 ID 的测试函数。如果读回来的 ID 和数据手册对不上,那就要怀疑是不是 SPI 时序配错了,或者芯片是山寨货。我遇到过几次山寨 ILI9341,读 ID 返回 0xFF,后来换了正品就好了。

3.5 本章知识结构图

下面这张图,把三款芯片的选型逻辑和数据手册阅读流程串起来了。你可以把它当作一个快速决策指南。

SPI LCD 驱动芯片选型与数据手册阅读流程 需要什么类型的屏? 彩色大屏 → ILI9341 彩色小屏 → ST7789 单色低功耗 → SSD1306 拿到数据手册,按以下步骤阅读 ① 找接口时序 SPI Mode / 时钟频率 ② 找初始化序列 上电流程 / 命令列表 ③ 理解显存操作 窗口模式 / 像素格式 ④ 寄存器列表 关键命令 / 参数定义 编写 SPI 驱动初始化代码 提示:读 ID 命令是验证芯片型号和 SPI 通信是否正常的最快方法

这张图的核心逻辑是:先根据项目需求选芯片,再按四个步骤啃数据手册,最后写出驱动代码。每一步都有对应的知识点,后面章节会逐一展开。

3.6 小结

这一章我们聊了三款主流 SPI LCD 驱动芯片的差异,也讲了数据手册怎么读。说白了,选型就是看分辨率、颜色、功耗、成本。读手册就是抓时序、初始化、显存操作、寄存器这四个重点。