3、显示时序配置:VESA/CEA标准、DTS中display-timings配置、时钟计算

各位同学,咱们今天聊点硬核的——显示时序。说白了,就是告诉屏幕「什么时候该刷新哪一行像素」。这玩意儿要是配错了,轻则画面撕裂,重则直接黑屏。我在A133上调过不下二十款屏幕,从古老的LVDS到最新的MIPI DSI,踩过的坑能写满一本笔记本。

3.1 VESA与CEA标准:两个江湖门派

显示时序标准,主要分两派:VESA和CEA。VESA是计算机显示器那帮人定的,CEA是电视行业搞的。你想想看,一个显示器厂商和一个电视厂商坐在一起开会,能聊到一块儿去吗?

VESA标准(比如CVT、GTF)讲究的是「精确」。每个像素、每行扫描线都有严格的时间要求。我习惯用VESA的CVT(Coordinated Video Timings)标准,因为它能自动计算出最优的消隐区间,省电又稳定。

CEA标准(比如CEA-861)则更「灵活」。它定义的是视频格式,比如1080p60、4K30这些。CEA标准里有个好东西——VIC(Video Identification Code),一个数字就能代表整套时序参数。我在调试HDMI输出时,经常靠VIC来快速匹配显示器。

核心区别一句话:VESA管的是「怎么画」,CEA管的是「画什么」。

3.2 DTS中的display-timings配置

在A133的Linux内核里,时序配置藏在设备树(DTS)中。路径一般是:

panel: panel {
    compatible = "simple-panel";
    
    display-timings {
        native-mode = <&timing0>;
        
        timing0: timing0 {
            clock-frequency = <74250000>;  /* 像素时钟,单位Hz */
            hactive = <1280>;              /* 水平有效像素 */
            vactive = <720>;               /* 垂直有效行数 */
            hfront-porch = <110>;          /* 水平前沿 */
            hback-porch = <220>;           /* 水平后沿 */
            hsync-len = <40>;              /* 水平同步宽度 */
            vfront-porch = <5>;            /* 垂直前沿 */
            vback-porch = <20>;            /* 垂直后沿 */
            vsync-len = <5>;               /* 垂直同步宽度 */
            hsync-active = <0>;            /* 水平同步极性,0低有效 */
            vsync-active = <0>;            /* 垂直同步极性,0低有效 */
            de-active = <0>;               /* 数据使能极性 */
            pixelclk-active = <0>;         /* 像素时钟极性 */
        };
    };
};

嗯,这里要注意:clock-frequency 是整块面板的「心跳」。我遇到过好几次,明明时序参数都对,但屏幕就是闪,最后发现是时钟频率算错了。

我的小技巧:在DTS里加个 status = "okay"; 之前,先用示波器量一下MIPI DSI的时钟通道。如果频率偏差超过1%,大概率要出问题。

3.3 时钟计算:别让数学卡住你

时钟频率怎么算?其实就一个公式:

像素时钟 = (hactive + hfront_porch + hback_porch + hsync_len) 
          × (vactive + vfront_porch + vback_porch + vsync_len) 
          × 刷新率

举个例子,1280x720@60Hz的典型时序:

参数
水平总像素 1280 + 110 + 220 + 40 = 1650
垂直总行数 720 + 5 + 20 + 5 = 750
像素时钟 1650 × 750 × 60 = 74.25 MHz

你看,算出来正好是74.25MHz。这就是CEA标准里720p60的经典值。我在项目中遇到过,有人把hfront-porch和hback-porch搞反了,结果画面整体偏移了半个屏幕。排查了整整一天,最后发现是DTS里写反了。

避坑指南:我曾经在调试一款4K@30Hz的屏幕时,按照公式算出来时钟频率是297MHz。但A133的HDMI输出最高只支持到300MHz。理论上能跑,但实际测试时发现EMI超标了。最后不得不把刷新率降到29.97Hz,才勉强通过认证。

3.4 实战中的那些坑

说几个我踩过的雷:

  • 极性搞反:hsync-active和vsync-active的极性,不同屏幕可能不一样。我习惯先查屏幕数据手册,如果手册没写,就默认设成0(低有效),然后看画面是否稳定。
  • 消隐区间太小:有些屏幕为了省成本,把消隐区间压得很小。但A133的DE(数据使能)信号需要一定的消隐时间来切换。我建议hblank至少留40个像素,vblank至少留4行。
  • 时钟抖动:如果屏幕出现水波纹,大概率是时钟抖动太大。可以尝试在DTS里调整pixelclk-active的极性,或者加一个RC滤波电路。

我的调试流程:

  1. 先确认屏幕数据手册里的时序参数
  2. 用公式算出像素时钟
  3. 在DTS里配好,编译烧录
  4. 用示波器量MIPI DSI的时钟通道,确认频率
  5. 如果画面异常,先检查极性,再检查消隐区间

最后说一句,显示时序这东西,理论是基础,但真正吃透还得靠实战。我建议你手头准备一块示波器,每次调完时序都去量一下。时间长了,你看到屏幕闪一下,就能猜出是哪个参数出了问题。