1. HDMI接口基础

做FPGA图像处理这些年,HDMI接口是我打交道最多的视频接口之一。说实话,刚接触那会儿我也被那些协议栈搞得头大——TMDS编码、DDC通道、EDID数据块……但搞明白之后你会发现,HDMI其实没那么玄乎。

今天我们就从最基础的东西聊起。把HDMI的底裤扒干净,后面做采集和DDR读写才不慌。

1.1 HDMI标准演进——从1.0到2.1

HDMI标准从2002年发布到现在,经历了多个版本。我最早做项目用的是HDMI 1.3,那时候1080p@60Hz就算高清了。现在2.1版本都支持8K@60Hz了,带宽飙到48Gbps。

下面这张表是我整理的几个关键版本对比,做FPGA选型时经常要翻出来看:

版本 最大带宽 最大分辨率 关键特性
HDMI 1.0 4.95 Gbps 1080p@60Hz 基础TMDS编码
HDMI 1.4 10.2 Gbps 4K@30Hz 以太网通道、ARC音频回传
HDMI 2.0 18 Gbps 4K@60Hz 支持BT.2020色域
HDMI 2.1 48 Gbps 8K@60Hz FRL模式、DSC压缩

重点提醒:做FPGA采集卡时,HDMI 1.4和2.0用的还是TMDS编码,到了2.1就换成FRL(Fixed Rate Link)模式了。如果你现在做项目,建议直接支持2.0,兼容性最好。

1.2 TMDS编码原理——数据是怎么飞起来的

TMDS全称是Transition Minimized Differential Signaling,翻译过来就是「最小化传输差分信号」。名字挺长,但核心就两件事:

  1. 编码:把8位数据变成10位,减少跳变次数
  2. 传输:用差分信号高速发送

为什么要这么做?你想想看,如果数据里连续出现01010101,信号跳变太频繁,电磁干扰就大。TMDS通过编码让跳变次数尽量少,同时保证直流平衡。

TMDS编码器内部其实有两个算法路径:

  • 路径A:当数据中1的数量多,或者0和1连续出现时,取反后发送
  • 路径B:否则直接发送原始数据

编码器会计算两种路径的跳变次数,选跳变少的那一路。最后再根据直流平衡状态,决定是否把整个10位数据取反。

我的经验:在FPGA里实现TMDS编码器,我建议直接用Xilinx的OSERDES原语。自己写逻辑的话,时序很容易跑不到1.65Gbps(1080p@60Hz的TMDS时钟)。

下面这张图展示了TMDS编码的基本流程,我画了个简化的框图:

TMDS编码流程框图 8位数据 TMDS编码器 (最小化跳变 + 直流平衡) 10位数据 并串转换 (OSERDES) 差分对 控制信号 (DE, HSync, VSync) 时钟通道 (像素时钟) HDMI有3个数据通道 + 1个时钟通道,每个通道独立进行TMDS编码

注意:TMDS编码后的10位数据,在接收端需要用IDELAY做动态延迟校准。我曾经在一个项目里没做眼图优化,结果线缆长了点就出现雪花点,折腾了两天才找到原因。

1.3 HDMI连接器引脚定义——别焊错了

HDMI连接器分Type A(标准)、Type C(mini)和Type D(micro)。做FPGA开发板最常见的是Type A,19个引脚。

我刚开始做硬件时,有次把TMDS数据2和时钟通道焊反了,查了三天才发现。嗯,从那以后我每次画原理图都要对着引脚定义核对三遍。

Type A连接器关键引脚如下:

引脚 信号 说明
1, 4, 7 TMDS Data 0/1/2+ 三路数据通道正极
3, 6, 9 TMDS Data 0/1/2- 三路数据通道负极
10, 12 TMDS Clock +/− 时钟通道
15 SCL DDC时钟线 (I2C)
16 SDA DDC数据线 (I2C)
18 +5V 电源输出 (最大50mA)
19 HPD 热插拔检测

布局建议:TMDS差分对要做等长布线,误差控制在±5mil以内。我一般会在PCB上预留π型滤波器的位置,万一EMI超标还能补救。

1.4 EDID与DDC协议——显示器在说什么悄悄话

EDID(Extended Display Identification Data)是显示器告诉显卡「我能支持什么分辨率」的数据块。DDC(Display Data Channel)就是传输EDID的I2C通道。

说白了,HDMI源端(比如你的FPGA板)上电后,会通过DDC通道读取显示器的EDID,然后根据EDID里的信息选择合适的分辨率和刷新率。

EDID数据块有128字节,结构如下:

  • 字节0-7:头部标识,固定为00 FF FF FF FF FF FF 00
  • 字节8-17:厂商信息、产品ID
  • 字节18-53:EDID版本、基本显示参数
  • 字节54-125:详细时序描述(DTD),最多4个
  • 字节126-127:校验和

做HDMI采集卡时,我建议直接用一个EEPROM存储EDID数据。FPGA上电后通过I2C读取EEPROM,再响应显示器的DDC请求。

核心要点:EDID里的详细时序描述(DTD)包含了分辨率、刷新率、像素时钟等信息。FPGA解析这些参数后,才能正确配置PLL和DDR控制器。

DDC协议其实就是标准的I2C通信,地址是0xA0(写)和0xA1(读)。时序要求如下:

  • I2C时钟频率:100kHz(标准模式)或400kHz(快速模式)
  • 起始条件:SCL高电平时SDA下降沿
  • 停止条件:SCL高电平时SDA上升沿
  • 应答:每字节后接收方拉低SDA

我曾经在一个项目里遇到EDID读取失败的问题,用示波器抓I2C波形才发现是上拉电阻选小了,导致上升沿太慢。换成4.7kΩ后问题解决。

好了,HDMI接口基础就聊到这儿。这些内容看着多,但做项目时你会发现,真正需要关心的就是TMDS编码怎么在FPGA里实现、EDID怎么解析、DDC怎么通信。后面做采集实战时,这些知识都会用上。

小技巧:调试HDMI时,我习惯先测HPD信号——如果显示器没拉高HPD,说明物理连接有问题,后面的TMDS和DDC都不用查了。

可可精品资料库