深入解析:屏幕撕裂、TE信号与显存同步机制
1. 核心概念:屏幕是如何显示的?
要理解撕裂,首先要理解嵌入式显示系统中的“双轨制”工作模式。系统中实际上有两个完全独立的“工人”在同时运作:
1.1 两个独立的循环
-
工人 A:屏幕驱动 IC (Driver IC)
-
角色:全自动复读机。
-
动作:光栅扫描 (Raster Scan)。不管外界发生什么,它都会以固定的频率(如 60Hz,即 16.6ms 一次),从 GRAM (显存) 中读取数据,逐行点亮屏幕像素(从左上角到右下角)。
-
特点:它的工作不会停止,也不会等人。
-
-
工人 B:MCU (主控芯片)
-
角色:送货员。
-
动作:写入 (Write)。通过 SPI/8080 接口将新的图像数据写入 Driver IC 的 GRAM 中。
-
特点:何时写、写多快,完全由 MCU 的性能和代码逻辑决定。
-
1.2 撕裂的本质 (The Tearing)
撕裂并非屏幕坏了,而是读写指针的“撞车”。
-
当 MCU 正在修改 GRAM 的某一行时,屏幕驱动刚好也扫描到这一行。
-
结果:屏幕的上半部分显示了旧的一帧,下半部分显示了新写入的一帧。中间的交界处出现断层,即“撕裂”。
2. 解决方案:TE 信号 (Tearing Effect)
为了防止撞车,我们需要一个交通信号灯。
-
定义:TE 是 Driver IC 输出给 MCU 的一个硬件脉冲信号。
-
时机:当屏幕扫描完一帧的最后一行,进入 V-Blank (垂直消隐期/回扫期) 时触发。
-
含义:告诉 MCU —— “我现在已经读完一帧了,正在休息准备回扫,这是你写入数据的黄金起跑线。”
3. 同步逻辑与速度竞赛
有了 TE 信号,MCU 就可以在“发令枪”响时起跑。但最终效果取决于 MCU 的写入速度。
我们假设屏幕刷新一帧需要 T_scan (16.6ms)。
场景一:MCU 写入速度 > 屏幕扫描速度 (理想状态)
-
过程:TE 信号触发 -> MCU 开始全速写入。
-
结果:MCU 的“写指针”跑得比屏幕的“读指针”快。屏幕读到的永远是 MCU 刚刚写好的新数据。
-
效果:完美无撕裂,60FPS。
场景二:MCU 写入速度 < 屏幕扫描速度 (但在 2 倍时间内)
-
条件:写入时间在
1x T_scan到2x T_scan之间(例如写完需 25ms)。 -
过程:
-
第 1 帧扫描:TE 触发,大家同时起跑。屏幕跑得快,MCU 跑得慢。屏幕读到的是旧数据(因为 MCU 还没来得及更新到屏幕指针的前面)。无撕裂。
-
第 2 帧扫描:屏幕开始第二圈追赶。因为 MCU 已经跑过一半了,只要在屏幕追上屁股之前写完,就不会发生数据冲突。
-
-
策略:TE 分频 (TE Skipping)。MCU 每隔一个 TE 信号写一次。
-
效果:无撕裂,帧率减半 (30FPS)。
4. 极限挑战:当写入速度极慢 ( > 2倍时间)
这是最容易产生误解的地方。如果 MCU 写一帧需要 40ms(远超 32ms)。
4.1 单显存系统 (Single Buffer) —— 大多数嵌入式屏幕
绝大多数 SPI/8080 屏幕只有一块 GRAM。
-
问题:即使你跳过 TE,等到第 3 个 TE 再写,当你开始写的时候,只要你写的持续时间太长,屏幕的扫描指针(读指针)最终会在下一轮扫描中从后面追上你的写指针(套圈)。
-
后果:一旦被追上,屏幕读取的数据瞬间从“新”变“旧”。
-
结论:在单显存系统中,只要写入速度过慢(发生套圈),撕裂是物理上不可避免的。 TE 只能固定撕裂的位置,无法消除它。
4.2 双显存系统 (Double Buffer) —— 终极解决方案
如果必须在慢速 MCU 上实现无撕裂,必须使用双缓冲。
-
原理:
-
Buffer A (前台):专门给屏幕读,显示画面。
-
Buffer B (后台):专门给 MCU 写。
-
-
流程:
-
MCU 慢慢地在 Buffer B 上画画,画 100ms 也没关系。此时屏幕一直显示 Buffer A(静止画面)。
-
画完后,MCU 等待下一个 TE 信号。
-
TE 到来,MCU 发指令互换指针:“以后去读 Buffer B!”
-
屏幕瞬间切换显示 Buffer B。
-
-
结论:只有双缓冲才能在任意低速写入下保证绝对不撕裂。
5. 总结对照表
| 硬件配置 | MCU 写入速度 | 是否使用 TE | 最终效果 | 备注 |
| 单显存 | 快 (<16ms) | ✅ 是 | 完美流畅 (60FPS) | 最佳体验 |
| 单显存 | 中等 (16~32ms) | ✅ 是 (隔帧写) | 流畅无撕裂 (30FPS) | 利用了起跑优势,没被套圈 |
| 单显存 | 慢 (>32ms) | ✅ 是 | 必有撕裂 | 发生了“套圈”,物理无解 |
| 单显存 | 任意 | ❌ 否 | 随机撕裂 (滚动) | 画面会有断层滚动干扰 |
| 双显存 | 任意 | ✅ 是 (用于切换) | 完美无撕裂 | 帧率取决于写入速度,但画面永远完整 |
6. 给开发者的建议
-
首选方案:优化代码、提升 SPI 时钟、使用 DMA,尽最大努力让写入时间小于 16ms(或者至少小于 32ms)。
-
避免误区:不要以为开了 TE 就万事大吉。如果你用的是普通单显存屏幕且画图很慢(比如又要解压 JPEG 又要刷屏),撕裂是注定的。
-
规避策略:如果实在无法提升速度,也无法上双缓冲,尽量设计静态 UI,或者使用局部刷新(只刷新变动的小区域,让写入数据量变小,从而间接提升速度)。
228

被折叠的 条评论
为什么被折叠?



