4. LTDC时序配置:同步信号、前后肩与时钟频率

屏幕花屏,十次有八次是时序配错了。

这话可能有点绝对,但在我这些年接触的TouchGFX项目里,LTDC时序配置确实是翻车重灾区。你想想看,MCU和LCD面板之间要握手,要同步,要告诉屏幕「我从哪一行开始画」「我画到哪一行了」「这一行结束了」。这些信息全靠几个信号线来传递。任何一个信号的时序对不上,画面就会错位、撕裂、甚至直接黑屏。

这一章,我们就来把这些信号彻底讲透。

4.1 LTDC同步信号:HSYNC和VSYNC

先说两个最核心的信号:HSYNC(行同步)和VSYNC(帧同步)。

HSYNC负责告诉屏幕:「新的一行要开始了」。VSYNC则负责告诉屏幕:「新的一帧要开始了」。你可以把VSYNC想象成翻书页的动作,HSYNC就是每一行文字的换行符。

这两个信号都是脉冲信号。平时保持高电平(或低电平,取决于配置),到了该同步的时候,拉低(或拉高)一个固定的脉冲宽度,然后再恢复。这个脉冲的宽度、位置、前后空闲时间,就是我们常说的时序参数。

关键概念:

  • HSYNC:水平同步,每行一个脉冲
  • VSYNC:垂直同步,每帧一个脉冲
  • 同步脉冲宽度:信号保持有效电平的时间
  • 前后肩:脉冲前后插入的空白周期

我刚开始做LCD驱动时,犯过一个低级错误——把HSYNC和VSYNC的极性搞反了。屏幕规格书写的是低电平有效,我配成了高电平有效。结果画面一直闪,查了两天才发现是这里的问题。嗯,从那以后我每次配时序都会先确认极性。

4.2 前后肩与同步脉冲

光有同步脉冲还不够。你想想看,屏幕收到HSYNC信号后,需要一点时间来「反应」——行驱动电路要稳定,像素时钟要对齐。所以,在真正的有效像素数据开始传输之前,需要插入一段空白周期。这就是前肩(HFP,Horizontal Front Porch)。

同样,一行数据传完之后,也需要一段空白让电路复位,准备接收下一行。这就是后肩(HBP,Horizontal Back Porch)。

垂直方向也一样,有VFP和VBP。

参数 全称 作用
HFP Horizontal Front Porch 行同步脉冲后的空白像素周期
HBP Horizontal Back Porch 行同步脉冲前的空白像素周期
VFP Vertical Front Porch 帧同步脉冲后的空白行周期
VBP Vertical Back Porch 帧同步脉冲前的空白行周期
HSYNC Horizontal Sync Pulse 行同步脉冲宽度
VSYNC Vertical Sync Pulse 帧同步脉冲宽度

这些参数从哪里来?从LCD面板的数据手册里来。每一块屏幕都会给出典型值和范围。我个人的习惯是:先用典型值,如果画面有偏移再微调。千万不要自己瞎猜,我曾经见过有人把HBP设成0,结果画面整体左移了半个屏幕。

小技巧:如果画面整体向右偏移,试着增加HBP;如果向左偏移,增加HFP。垂直方向同理。

4.3 时钟频率计算与匹配

时序参数配好了,时钟频率不对,照样花屏。

LTDC的像素时钟(Pixel Clock,简称PCLK)决定了每秒能传输多少个像素点。计算公式其实很简单:

PCLK = (H_Total) × (V_Total) × 帧率

其中:
H_Total = H_Active + HFP + HBP + HSYNC
V_Total = V_Active + VFP + VBP + VSYNC

举个例子。假设你的屏幕分辨率是800×480,帧率60fps,时序参数如下:

H_Active = 800
HFP = 40
HBP = 40
HSYNC = 48
H_Total = 800 + 40 + 40 + 48 = 928

V_Active = 480
VFP = 13
VBP = 29
VSYNC = 3
V_Total = 480 + 13 + 29 + 3 = 525

PCLK = 928 × 525 × 60 ≈ 29.2 MHz

算出来是29.2MHz。但你的MCU不一定能精确产生这个频率。比如STM32F429的LTDC时钟源来自PLL,分频系数是整数。你可能只能配到29.5MHz或者28.8MHz。这时候怎么办?

我的经验是:优先保证帧率稳定。稍微偏离一点目标帧率(比如59fps或61fps)通常看不出来,但时钟抖动或者分频不准导致的像素错位,一眼就能看出来。

注意:时钟频率不能超过LCD面板支持的最大值。很多廉价屏幕标称50MHz,实际跑到45MHz以上就开始丢像素了。我曾经在一个项目里把PCLK配到了48MHz,屏幕规格书说支持50MHz,结果画面顶部有一条彩色的噪点带。降回40MHz就正常了。所以,留点余量总是没错的。

4.4 时序配置的完整流程

说了这么多,我们来梳理一下实际操作步骤:

  1. 查手册:找到LCD面板的时序参数表,记下HFP、HBP、HSYNC、VFP、VBP、VSYNC的典型值
  2. 算总长:计算H_Total和V_Total
  3. 算时钟:根据目标帧率计算PCLK
  4. 配时钟树:在MCU的时钟配置里,找到最接近的PCLK频率
  5. 配寄存器:把时序参数写入LTDC的同步配置寄存器
  6. 验证:上电看画面,如果偏移或花屏,微调前后肩

下面这张图可以帮你理清整个时序配置的逻辑关系:

LTDC时序配置核心逻辑 LCD数据手册 获取时序参数 计算H_Total/V_Total H_Active + HFP + HBP + HSYNC 计算PCLK H_Total × V_Total × 帧率 配置MCU时钟树 PLL分频,匹配PCLK 配置LTDC寄存器 写入HFP/HBP/HSYNC等 上电验证 检查偏移/花屏 画面异常?微调前后肩或时钟 💡 核心原则: 1. 所有参数以LCD数据手册为准,不要猜测 2. 时钟频率留10%余量,避免信号完整性问题

4.5 实战中的常见坑

最后,分享几个我在项目中踩过的坑:

  • 坑一:忽略DE信号。有些屏幕用DE(Data Enable)信号代替HSYNC/VSYNC来指示有效数据区域。如果你配了同步信号但没配DE极性,画面可能完全不显示。
  • 坑二:前后肩设得太小。有些工程师为了「压榨」带宽,把HFP和HBP设成最小值。结果屏幕内部电路来不及稳定,画面边缘出现重影。我建议至少留4-8个像素的余量。
  • 坑三:时钟频率算错。记得有一次我把H_Total算成了H_Active + HFP + HBP,忘了加HSYNC的宽度。结果算出来的PCLK偏小,帧率只有50fps,画面明显卡顿。
  • 坑四:分频系数选错。STM32的LTDC时钟来自PLL3R或者PLLSAI,分频系数是整数。如果你需要的PCLK是29.2MHz,但分频后只能得到29.8MHz,别硬上。稍微调一下帧率目标,让PCLK落在整数分频点上。

我的调试习惯:先用逻辑分析仪抓一下HSYNC和VSYNC的波形,确认脉冲宽度和周期对不对。这一步能帮你排除一半的时序问题。