视频时序基础:像素时钟、行场同步信号、有效数据窗口、VESA与CEA时序标准

做HDMI输出,说白了就是在跟时间打交道。

我刚开始接触视频接口时,总觉得这东西很玄乎——一根线怎么就能传那么清晰的画面?后来拆开时序图一看,嗯,其实就是个精确到纳秒的「扫描」过程。今天咱们就把视频时序的底裤扒干净。

像素时钟:整个系统的节拍器

视频信号里最基础的东西,就是像素时钟。你可以把它想象成乐队指挥手里的节拍器——每个节拍,就传输一个像素的数据。

举个例子,1080p60(1920×1080,60Hz)需要多大的像素时钟?

简单算一下:1920 × 1080 × 60 ≈ 124.4 MHz。但等等,这还没完。实际传输时,每行和每帧之间都有「空白区」,也就是消隐区。所以实际像素时钟要比这个高。

关键公式:

像素时钟 = 水平总像素 × 垂直总行数 × 刷新率

其中「总像素」和「总行数」都包含消隐区。

我在项目中遇到过一块FPGA开发板,标称支持1080p60,结果死活出不来画面。查了半天,发现是PLL锁相环配置不对,像素时钟差了0.5%。你想想看,0.5%的偏差,画面就开始闪烁、抖动。所以时钟精度必须控制在±50ppm以内,这是硬指标。

行同步与场同步:画面的「换行」和「翻页」

有了像素时钟,我们还需要告诉显示器:「这一行画完了,换下一行」以及「这一帧画完了,换下一帧」。这就是行同步(HSYNC)和场同步(VSYNC)信号干的事。

行同步信号,每画完一行就拉低一次,持续几个像素时钟周期。场同步信号,每画完一帧就拉低一次,持续几行的时间。

我习惯把行同步比作打字机的回车键,场同步就是换纸。虽然现在没人用打字机了,但这个比喻挺形象的。

避坑指南:

我曾经在调试4K@60Hz输出时,行同步的脉冲宽度设窄了2个像素时钟。结果画面顶部出现了一条细细的闪烁线。后来查VESA标准才发现,不同分辨率对同步脉冲宽度有严格要求,不能随便改。

有效数据窗口:真正干活的时间

整个视频传输周期里,只有一部分时间在传真正的像素数据,其余时间都在「空转」——这就是消隐区。

有效数据窗口,就是行有效(HACTIVE)和场有效(VACTIVE)同时为真的那段时间。说白了,就是画面真正显示内容的部分。

举个例子,1080p60的典型时序:

参数 值 说明
水平有效像素 1920 真正显示的画面宽度
水平消隐 280 包含HFP、HSYNC、HBP
水平总像素 2200 1920 + 280
垂直有效行 1080 真正显示的画面高度
垂直消隐 45 包含VFP、VSYNC、VBP
垂直总行数 1125 1080 + 45

你看,每帧有1125行,但只有1080行是有效数据。剩下的45行在干嘛?在等电子枪回扫(虽然现在都是数字信号了,但时序概念保留了下来)。

VESA与CEA时序标准:两个江湖

视频时序标准主要有两派:VESA和CEA。

VESA(Video Electronics Standards Association)主要管显示器、电脑显卡这块。它的时序特点是:消隐区比较大,同步信号位置固定。我最早接触的就是VESA的CVT(Coordinated Video Timings)标准,那个文档写得真叫一个详细。

CEA(Consumer Electronics Association)主要管电视、消费电子这块。它的时序特点是:消隐区小,更紧凑。HDMI标准里大量引用了CEA-861系列的时序定义。

核心区别:

  • VESA:消隐区大,兼容性好,适合显示器
  • CEA:消隐区小,带宽利用率高,适合电视
  • HDMI同时支持两者,但EDID里会标明设备支持哪种

我记得有一次调试一个投影仪项目,EDID里写的是CEA时序,但我按VESA的CVT去配,结果画面偏左了大概20个像素。后来一查,原来是行前肩(HFP)的宽度不一样。嗯,从那以后我每次读EDID都会仔细看timing descriptor。

时序参数详解:HFP、HSYNC、HBP、VFP、VSYNC、VBP

这几个缩写,做视频的应该闭着眼睛都能背出来:

  • HFP(Horizontal Front Porch):行前肩,有效数据结束到行同步开始之间的空白
  • HSYNC(Horizontal Sync):行同步脉冲,告诉显示器换行
  • HBP(Horizontal Back Porch):行后肩,行同步结束到下一行有效数据开始之间的空白
  • VFP(Vertical Front Porch):场前肩,类似HFP,不过是垂直方向
  • VSYNC(Vertical Sync):场同步脉冲,告诉显示器换帧
  • VBP(Vertical Back Porch):场后肩,类似HBP,垂直方向

这些参数不是随便定的。VESA和CEA标准里,每个分辨率都有精确的数值。你改一个像素,可能画面就歪了。

特别注意:

我曾经为了省带宽,把HBP从88个像素减到44个。结果画面右侧出现了一条垂直的彩色条纹。后来才知道,HBP不仅是时序要求,还给了显示器足够的时间去锁相环重新锁定。减太多,显示器就来不及同步了。

SVG时序结构图

下面这张图,是我自己画的一行视频信号的时序结构。你看一眼就明白了:

一行视频信号时序结构 HACTIVE(有效数据) HFP HSYNC HBP 下一行 0 HACTIVE结束 HSYNC开始 HSYNC结束 HBP结束 垂直方向类似,只是单位从「像素」变成「行」 VACTIVE(有效行,如1080行) VFP + VSYNC + VBP(垂直消隐区,如45行) 有效数据 消隐区 同步脉冲

这张图里,一行信号从左到右依次是:有效数据区(HACTIVE)、行前肩(HFP)、行同步脉冲(HSYNC)、行后肩(HBP),然后进入下一行的有效数据区。垂直方向完全同理,只是把「像素」换成「行」。

实际项目中的时序配置

做HDMI输出时,时序配置通常写在FPGA的寄存器里,或者通过I2C配置给HDMI发送芯片。我常用的做法是:

// 以1080p60为例,CEA-861标准时序
// 像素时钟:148.5 MHz
// 水平参数(单位:像素时钟周期)
#define H_ACTIVE    1920
#define H_FP        88
#define H_SYNC      44
#define H_BP        148
#define H_TOTAL     2200  // 1920+88+44+148

// 垂直参数(单位:行)
#define V_ACTIVE    1080
#define V_FP        4
#define V_SYNC      5
#define V_BP        36
#define V_TOTAL     1125  // 1080+4+5+36

这段代码我用了好多年,每次新项目都直接复制过去改改参数。但有一点要注意:不同刷新率(59.94Hz vs 60Hz)的参数有细微差别,别搞混了。

我的习惯:

每次配时序前,先去VESA或CEA官网下载最新的时序表格。网上流传的很多参数都是错的,我吃过这个亏。另外,HDMI的TMDS时钟是像素时钟的10倍(对于8bit色深),这个别忘了。

视频时序这东西,说白了就是「精确到像素的排队」。像素时钟决定速度,行场同步决定换行换帧,有效数据窗口决定画面内容。VESA和CEA两个标准,一个偏电脑,一个偏电视,但核心逻辑一模一样。

嗯,掌握了这些,HDMI输出的底层你就拿下了。下一层就是怎么把这些时序信号和实际像素数据打包成TMDS差分信号,那是另一个话题了。


可可精品资料库