2、硬件基础:显示时序参数与像素时钟计算

做显示驱动,第一关就是搞懂时序。说白了,屏幕不是你想画就能画的,它有一套严格的规矩——什么时候发数据,什么时候告诉屏幕“我要换行了”,什么时候说“这一帧结束了”。这些规矩,就是显示时序。

我刚开始接触LCD驱动时,看着数据手册里那一堆缩写——HFP、HBP、HSYNC、VFP、VBP、VSYNC——头都大了。后来发现,其实就两件事:行时序和帧时序。搞懂了,后面像素时钟、刷新率什么的,自然就通了。

2.1 行时序(Horizontal Timing)

先看一行数据怎么传。屏幕从左到右扫一行,不是一口气把像素全发完就完事。中间有“空档期”,用来让屏幕准备好接收下一行数据。

参数 全称 说明
HSYNC Horizontal Sync 行同步脉冲。告诉屏幕“新一行要开始了”
HBP Horizontal Back Porch 行同步后的消隐区。等屏幕稳定下来
HACT Horizontal Active 有效像素数据。比如1024列,就是1024个像素
HFP Horizontal Front Porch 行同步前的消隐区。给屏幕一点缓冲时间

一行总长度 = HSYNC + HBP + HACT + HFP。单位是像素时钟周期。

我的经验:调试时如果屏幕出现“左移”或“右移”的画面,多半是HBP或HFP没配对。我曾经调一块800×480的屏,画面整体偏右了20个像素,查了半天,原来是HBP少写了20个时钟周期。

2.2 帧时序(Vertical Timing)

行搞定了,再看帧。一帧就是一幅完整的画面。帧时序和行时序非常像,只是把“行”换成了“帧”,把“像素”换成了“行”。

参数 全称 说明
VSYNC Vertical Sync 帧同步脉冲。告诉屏幕“新一帧要开始了”
VBP Vertical Back Porch 帧同步后的消隐区
VACT Vertical Active 有效行数。比如600行
VFP Vertical Front Porch 帧同步前的消隐区

一帧总行数 = VSYNC + VBP + VACT + VFP。单位是行。

注意:有些屏的时序参数是“包含”关系,比如VSYNC已经包含了VBP的一部分。一定要看数据手册的时序图,别想当然。我曾经因为没仔细看时序图,把VSYNC和VBP算重了,结果画面一直闪。

2.3 像素时钟计算

像素时钟(Pixel Clock,简称PCLK)是驱动器的“心跳”。它决定了每秒能传多少个像素。

公式很简单:

PCLK = (H_total) × (V_total) × 刷新率

其中:
H_total = HSYNC + HBP + HACT + HFP
V_total = VSYNC + VBP + VACT + VFP

举个例子。一块1024×600的屏,刷新率60Hz,时序参数如下:

参数 值
HSYNC 30
HBP 40
HACT 1024
HFP 10
VSYNC 3
VBP 10
VACT 600
VFP 5

算一下:

H_total = 30 + 40 + 1024 + 10 = 1104
V_total = 3 + 10 + 600 + 5 = 618
PCLK = 1104 × 618 × 60 ≈ 40.9 MHz

所以,你需要一个约41MHz的像素时钟。实际选时钟源时,我会留一点余量,比如选个42MHz或45MHz的晶振,然后用PLL分频得到精确值。

关键点:像素时钟不是只算有效像素,而是算上所有消隐区。很多人只算了1024×600×60,得出36.8MHz,结果屏死活不亮。嗯,我当年也犯过这个错。

2.4 分辨率与刷新率的关系

分辨率越高,刷新率越高,需要的像素时钟就越高。但像素时钟不是无限高的——受限于硬件接口带宽。

举个例子:

  • 640×480 @ 60Hz:PCLK ≈ 25MHz
  • 1024×600 @ 60Hz:PCLK ≈ 41MHz
  • 1920×1080 @ 60Hz:PCLK ≈ 148MHz
  • 1920×1080 @ 120Hz:PCLK ≈ 297MHz

你看,从1080p 60Hz到120Hz,像素时钟直接翻倍。很多嵌入式芯片的LCD控制器最高只能跑到150MHz左右,所以想上高刷,就得降分辨率,或者用更高效的接口(比如MIPI DSI)。

避坑指南:我曾经在一个项目里,想用STM32F4的LTDC驱动一块1024×600的屏,结果发现LTDC最高只能到90MHz。算了一下,60Hz需要41MHz,没问题。但客户非要75Hz,一算需要51MHz,超了。最后只能降回60Hz。所以选型时一定要先算好像素时钟,别等画板了才发现跑不动。

2.5 时序参数与像素时钟的关系图

下面这张图,把行时序、帧时序和像素时钟的关系串起来了。你看一遍,应该就能记住整个流程。

显示时序与像素时钟关系图 行时序(一行) HSYNC 30 clk HBP 40 clk HACT(有效像素) 1024 clk HFP 10 clk H_total = 30 + 40 + 1024 + 10 = 1104 clk 帧时序(一帧) VSYNC 3 行 VBP 10 行 VACT(有效行数) 600 行 VFP 5 行 V_total = 3 + 10 + 600 + 5 = 618 行 像素时钟计算 PCLK = H_total × V_total × 刷新率 = 1104 × 618 × 60 ≈ 40.9 MHz

从图里能清楚看到:一行里真正传像素的只有HACT那一段,其他都是“开销”。帧也一样。这些开销加起来,就是像素时钟的“水分”。

2.6 实际项目中的时序配置

拿到一块新屏,数据手册里通常会给出时序参数的最小值、典型值、最大值。我一般这样配:

  1. 先看典型值——大多数情况下直接用典型值就能正常工作。
  2. 如果画面有异常(比如闪烁、偏移),再微调HBP和VBP。增大消隐区通常能提高稳定性,但会降低刷新率。
  3. 像素时钟用公式算出来之后,选一个能整除的时钟源。比如40.9MHz,可以选40.5MHz或41MHz,差别不大。
注意:有些屏对时序非常敏感,尤其是那些“非标”分辨率。我调过一块480×272的屏,典型值怎么配都不行,最后把HBP从40改成45,画面就稳了。所以,别死磕数据手册,该试就试。

好了,时序参数和像素时钟的计算,到这里就讲完了。你只要记住:行时序管一行,帧时序管一帧,像素时钟是总带宽。后面写驱动代码时,这些参数会直接填进LCD控制器的寄存器里。配对了,屏就亮;配错了,屏就黑。就这么简单。