一、LCD显示原理:液晶显示的基本原理、像素与分辨率、色彩深度与RGB模型
各位同学,咱们今天正式开讲。做嵌入式LCD驱动,你光会写代码不行,得先搞明白屏幕到底是怎么把图像“变”出来的。我当年刚入行时,上来就对着数据手册调时序,结果画面花得一塌糊涂,折腾了两天才发现——我连像素怎么刷新的都没搞懂。嗯,这课咱们就从根上捋一遍。
1.1 液晶显示的基本原理
液晶,说白了是一种介于固体和液体之间的物质。它自己不会发光,但给它加个电场,它里面的分子就会扭转方向。你想想看,分子一转,光线透过率就变了——这就是液晶显示最核心的物理基础。
一个典型的LCD模组,从背光层到人眼,大致经过这么几层:
- 背光源(Backlight):通常是LED灯条,提供白色底光。
- 偏光片(Polarizer):只让特定方向的光通过。
- 液晶层(Liquid Crystal Layer):电场控制分子扭转,改变偏振方向。
- 彩色滤光片(Color Filter):红、绿、蓝三色子像素排列。
- 第二层偏光片:与第一层配合,决定最终出光量。
我在一个工业仪表项目里遇到过,背光选型没注意色温,结果屏幕偏蓝得厉害。后来换了高显色指数的LED,才把颜色拉回来。所以背光不是“能亮就行”,色温和均匀度都很关键。
核心要点:液晶本身不发光,它只是个“光阀门”。背光常亮,液晶分子扭转控制每个子像素的透光率,从而形成灰度,再配合彩色滤光片合成彩色图像。
下面这张图,把LCD显示的基本流程画清楚了:
1.2 像素与分辨率
像素(Pixel)是图像的最小单位。一个像素包含R、G、B三个子像素。分辨率就是屏幕在横向和纵向上有多少个像素。比如320×240,就是横向320个像素,纵向240行。
我建议你选屏时,先看分辨率,再看尺寸。分辨率决定了你能显示多少细节,尺寸决定了物理大小。同样320×240,2.8寸和3.5寸的屏,点距不一样,显示效果差很多。
| 分辨率 | 常见尺寸 | 像素总数 | 典型应用 |
|---|---|---|---|
| 128×64 | 0.96" ~ 1.3" | 8,192 | 小家电、温控器 |
| 320×240 | 2.8" ~ 3.5" | 76,800 | 手持仪表、工控屏 |
| 480×320 | 3.5" ~ 4.3" | 153,600 | 智能家居、HMI |
| 800×480 | 4.3" ~ 7.0" | 384,000 | 车载、医疗设备 |
个人经验:做单片机驱动时,分辨率直接决定了你的帧缓冲区大小。320×240、16位色,缓冲区就是320×240×2 = 153,600字节。如果你的MCU只有64KB RAM,那就得考虑分块刷新或者用SPI串行屏了。我曾经在一个项目里硬塞全帧缓冲,结果堆栈溢出了……嗯,从那以后我选屏前都会先算一遍RAM账。
1.3 色彩深度与RGB模型
色彩深度,也叫色深,指的是每个像素用多少位来表示颜色。位数越多,能显示的颜色就越多。
常见的色深有:
- 1位:黑白,每个像素要么亮要么灭。
- 8位:256色,通常用索引色表。
- 16位:65,536色,RGB565格式最常见。
- 18位:262,144色,RGB666,很多中端屏用这个。
- 24位:16,777,216色,RGB888,真彩色。
RGB模型,就是把红、绿、蓝三个分量组合成一个颜色。每个分量用一个数值表示强度。0最暗,最大值最亮。
咱们做单片机驱动,最常用的是RGB565。为什么?因为16位正好是两个字节,MCU处理起来效率高。RGB565的分配是这样的:
| 位 | 15-11 | 10-5 | 4-0 |
|---|---|---|---|
| 分量 | R(红色) | G(绿色) | B(蓝色) |
| 位数 | 5位 | 6位 | 5位 |
| 取值范围 | 0-31 | 0-63 | 0-31 |
你想想看,绿色多给了一位,因为人眼对绿色最敏感。这是硬件设计上的一个小trick。
注意:RGB565转RGB888时,不能直接左移补零。比如5位的R值31(0x1F),左移3位变成0xF8,但实际应该映射到0xFF。正确的做法是高位补低位:R_8bit = (R_5bit << 3) | (R_5bit >> 2)。我见过不少新手在这里踩坑,显示出来的颜色总是偏暗。
下面这张图,把RGB565的数据结构展示得更直观:
实际编程中,我们经常需要把RGB888转成RGB565。代码很简单:
// RGB888 转 RGB565
// r, g, b 取值范围 0-255
uint16_t rgb565(uint8_t r, uint8_t g, uint8_t b) {
return ((r & 0xF8) << 8) | // R[7:3] → 位15-11
((g & 0xFC) << 3) | // G[7:2] → 位10-5
(b >> 3); // B[7:3] → 位4-0
}
这段代码我用了好多年,基本没出过问题。唯一要注意的是,有些LCD控制器对字节序有要求——到底是高字节在前还是低字节在前,得看数据手册。我建议你拿到新屏后,先写个纯红色(0xF800)测试一下,如果显示出来是蓝色,那就是字节序反了。
本章小结:LCD显示的本质是“背光+液晶光阀门+彩色滤光片”。像素是显示的最小单元,分辨率决定了画面精细度。色彩深度决定了颜色丰富度,RGB565是单片机驱动中最实用的格式。搞懂这些,后面调时序、画波形、写驱动,你心里就有底了。