2. 嵌入式GUI基础

做嵌入式GUI驱动,说白了就是跟显示面板打交道。你连屏幕怎么亮起来的都不清楚,那调试起来肯定抓瞎。这一章我把显示设备的基础知识掰开揉碎讲清楚,都是我在项目里踩过坑之后总结出来的东西。

2.1 LCD与OLED工作原理

先说说LCD。LCD本身不发光,它靠背后的背光模组照亮。液晶分子在电场作用下扭转,控制光线通过偏振片的量,从而显示不同亮度。每个像素由R、G、B三个子像素组成,通过调节电压改变液晶扭转角度,实现色彩混合。

我的经验:LCD的响应时间一般在10-30ms,低温下会变慢。我在北方做户外设备时,冬天屏幕拖影严重,后来换了宽温液晶才解决。如果你做车载或户外项目,务必关注工作温度范围。

OLED就不一样了。每个像素都是独立的有机发光二极管,通电就亮,不通电就黑。没有背光,所以黑色是真的黑,对比度极高。响应时间能做到微秒级,显示动态画面非常流畅。

核心区别:LCD需要背光,OLED自发光。OLED的黑色更纯粹,但寿命和烧屏问题是硬伤。我做过一个长期显示固定界面的工控屏,OLED用了两年就出现了明显的残影,后来换回了LCD。

2.2 分辨率与色彩深度

分辨率就是屏幕上有多少个像素点。常见的有:

  • QVGA:320×240,小屏设备常见
  • VGA:640×480,老式显示器标准
  • WVGA:800×480,很多7寸屏用这个
  • HD:1280×720,720p
  • FHD:1920×1080,1080p

分辨率越高,需要的显存和带宽就越大。举个例子,一个800×480的屏幕,如果色彩深度是16位,那每帧需要的显存是:

800 × 480 × 2 = 768,000 字节 ≈ 750KB

如果是24位真彩色,那就翻倍到1.5MB。你想想看,如果你的MCU只有几百KB的RAM,那根本存不下一帧画面。这时候就得用外部SDRAM或者压缩方案。

色彩深度决定了每个像素能显示多少种颜色:

色彩深度 颜色数 每像素字节数 常见场景
1位 2 0.125 单色屏、电子纸
8位 256 1 低端彩屏、索引色
16位(565) 65536 2 嵌入式GUI最常用
18位 262144 3 部分LCD控制器
24位 16777216 3 真彩色显示
注意:16位565格式是嵌入式GUI的黄金标准。R占5位,G占6位,B占5位。人眼对绿色最敏感,所以绿色多给了一位。我见过有人用16位555格式,结果绿色偏色严重,调试了半天才发现是格式没对齐。

2.3 接口类型

接口这块水很深。不同的接口决定了你的驱动方式、传输速度和硬件复杂度。我按使用频率从低到高给你捋一遍。

2.3.1 SPI接口

SPI是最简单的显示接口,一般用4线或3线模式。数据线少,适合小尺寸、低分辨率的屏幕。常见于128×64的OLED或小尺寸LCD。

  • 优点:引脚少(SCLK、MOSI、CS、DC),MCU几乎都支持
  • 缺点:速度慢,刷新率低,不适合大屏
  • 典型场景:手表、小仪表盘、状态指示屏

SPI的时钟频率一般能做到10-40MHz。但要注意,SPI是串行传输,每像素16位数据就要串行移出16个时钟周期。算一下:800×480的屏幕,用20MHz SPI刷新一帧需要:

800 × 480 × 16 / 20,000,000 ≈ 0.307秒

也就是3帧多一点。这还只是纯数据传输,没算命令开销。所以SPI只适合小屏。

避坑指南:我曾经用SPI驱动一个320×240的屏做动画,结果刷新率只有10fps,卡得不行。后来发现是SPI的DMA没开,CPU一直在轮询。开了DMA之后帧率翻了一倍。记住,SPI一定要配合DMA用。

2.3.2 I8080接口(MCU接口)

I8080是Intel早年定义的并行总线接口,在嵌入式屏幕里非常常见。它用8位或16位并行数据线,加上WR、RD、CS、DC、RESET等控制信号。

  • 优点:速度快,比SPI快好几倍,适合中小尺寸屏幕
  • 缺点:引脚多(16位模式需要20+个引脚),布线麻烦
  • 典型场景:3.5寸到7寸的LCD屏,很多MCU内置I8080控制器

I8080的时序其实很简单:拉低CS选中芯片,设置DC为命令或数据模式,然后拉低WR写数据。读操作类似,用RD信号。很多国产屏幕驱动IC(比如ILI9341、ST7789)都支持I8080接口。

// I8080 写数据示例(16位模式)
void LCD_WriteData(uint16_t data) {
    LCD_CS_LOW();          // 片选
    LCD_DC_HIGH();         // 数据模式
    LCD_DATA_PORT = data;  // 数据写入并行口
    LCD_WR_LOW();          // 写脉冲
    LCD_WR_HIGH();
    LCD_CS_HIGH();         // 释放片选
}
我的习惯:I8080接口的时序要求比较严格,特别是WR脉冲宽度。我一般用逻辑分析仪抓一下波形,确保建立时间和保持时间满足规格书要求。有一次我偷懒没查,结果屏幕显示花屏,查了两天才发现是GPIO速度配置太慢,WR脉冲宽度不够。

2.3.3 RGB接口

RGB接口是真正的并行视频接口。它直接把像素数据通过R、G、B三组数据线并行传输,加上HSYNC(行同步)、VSYNC(帧同步)、DCLK(像素时钟)和DE(数据使能)信号。

  • 优点:速度极快,支持高分辨率和高刷新率
  • 缺点:需要MCU有LCD控制器,引脚非常多(24位RGB需要30+个引脚)
  • 典型场景:7寸以上大屏、高清显示、视频播放

RGB接口没有显存的概念,数据是实时刷新的。MCU的LCD控制器会从SDRAM中读取帧缓冲数据,然后按照时序发送给屏幕。所以MCU必须要有足够的带宽来维持刷新率。

常见的RGB接口格式有:

格式 数据线数 颜色数 典型分辨率
RGB565 16 65536 800×480
RGB666 18 262144 1024×600
RGB888 24 16777216 1920×1080
注意:RGB接口的时序参数(HBP、HFP、VBP、VFP、Hsync宽度、Vsync宽度)必须严格按照屏幕规格书配置。我见过有人把HBP设错了,结果屏幕左边有一条黑边,调了一整天才发现是时序参数不对。

2.3.4 MIPI DSI接口

MIPI DSI是移动设备的主流接口,现在也越来越多地用在嵌入式领域。它采用差分信号传输,数据线可以配置为1-4 lane,每个lane的速率能到1Gbps以上。

  • 优点:高速、低功耗、抗干扰强、引脚少
  • 缺点:协议复杂,需要专门的MIPI控制器,调试困难
  • 典型场景:手机、平板、高端嵌入式设备

MIPI DSI有两种工作模式:

  • 命令模式:类似I8080,屏幕自带显存,MCU通过MIPI总线写显存
  • 视频模式:类似RGB接口,实时刷新,屏幕不自带显存

MIPI的调试是我最头疼的。信号质量要求高,PCB布线要严格控制阻抗(100Ω差分阻抗),走线长度要匹配。我做过一个项目,MIPI屏幕偶尔闪一下,查了半个月发现是PCB上MIPI走线绕了个弯,导致lane之间长度差了5mm,信号歪斜了。

我的建议:如果你刚开始接触MIPI,先买一个成熟的MIPI转接板或者开发板,把协议栈调通了再自己画板。MIPI的物理层调试需要示波器或者逻辑分析仪,别指望靠肉眼猜。

2.4 接口选择决策图

下面这张图是我自己总结的接口选择逻辑,帮你快速判断项目该用哪种接口。

显示接口选择决策图 显示接口选择决策图 屏幕尺寸与分辨率 小尺寸 < 3.5寸 SPI 接口 中等尺寸 3.5-7寸 I8080 接口 大尺寸 > 7寸 RGB 接口 帧率要求 < 15fps MCU内置LCD控制器 需要外部SDRAM 高帧率/高分辨率需求 → 考虑 MIPI DSI 说明: SPI适合低分辨率小屏,I8080适合中等尺寸,RGB适合大屏高刷,MIPI是高端方案但调试复杂。

2.5 接口对比总结

最后用一张表把四种接口的核心参数放在一起对比,方便你选型时参考。

参数 SPI I8080 RGB MIPI DSI
引脚数 4-6 12-24 20-40 4-10
最大速率 ~40MHz ~100MHz ~150MHz ~1Gbps/lane
典型分辨率 ≤320×240 ≤800×480 ≤1920×1080 ≥1920×1080
是否需要显存 屏幕自带 屏幕自带 外部SDRAM 外部SDRAM
协议复杂度 低 低 中 高
调试难度 低 低 中 高
功耗 低 中 高 低
总结一下:选接口不是越高级越好,而是看你的MCU资源、屏幕尺寸和帧率要求。我见过有人用STM32F103硬怼RGB 800×480,结果刷新率只有5fps,还不如用I8080。选型前先算带宽,再定接口,这是铁律。