4、多摄像头硬件同步方案:硬件触发线(FSIN/STROBE)、时钟同步(PPS)、硬件同步信号设计

多摄像头同步,说白了就是让多个摄像头在同一时刻「咔嚓」一下。你想想看,如果每个摄像头各自为政,拍出来的画面时间戳对不上,那后面的拼接、融合、3D重建全都会乱套。我在项目中遇到过最头疼的情况——四个摄像头采集的画面,时间差最大能到几十毫秒,做出来的全景图边缘全是撕裂的。

嗯,今天咱们就聊聊硬件同步的三种主流方案。我个人习惯把它们分成三个层次:触发线同步、时钟同步、以及自定义硬件同步信号。咱们一个一个来拆解。

4.1 硬件触发线:FSIN 与 STROBE

这是最直接、最常用的同步方式。说白了就是一根线,主控发一个脉冲,所有摄像头同时开始曝光。

FSIN(Frame Sync In),帧同步输入。大部分摄像头传感器都支持这个引脚。你给它一个上升沿,它就乖乖开始新一帧的曝光。我最早用OV系列传感器时,就是靠这个搞定的。

STROBE,有些厂商叫它「触发输入」。功能类似,但细节上有点区别。STROBE 通常用于控制曝光开始时刻,而 FSIN 更偏向于帧起始同步。

关键点:FSIN 信号的时序精度直接决定了同步误差。一般要求抖动小于传感器一行扫描时间。我建议用 GPIO 直接输出,别经过 I2C 或 SPI 转接,那玩意儿延迟不可控。

实际接线很简单:

// 伪代码:主控输出 FSIN 脉冲
void trigger_all_cameras(void) {
    // 拉高 FSIN 线
    HAL_GPIO_WritePin(FSIN_GPIO_Port, FSIN_Pin, GPIO_PIN_SET);
    // 保持至少 10us(具体看传感器手册)
    delay_us(10);
    // 拉低
    HAL_GPIO_WritePin(FSIN_GPIO_Port, FSIN_Pin, GPIO_PIN_RESET);
}

这里有个坑——我曾经遇到过 FSIN 信号反射导致误触发的情况。线长了,阻抗不匹配,脉冲会反弹。解决办法是在 FSIN 引脚附近加一个 100Ω 的串联电阻,吸收反射。

注意:多个摄像头的 FSIN 线不能简单并联!每个摄像头需要独立的驱动能力。我建议用 74HC244 之类的缓冲器做扇出,一个主控 GPIO 驱动多个缓冲器输入,每个缓冲器输出接一个摄像头。

4.2 时钟同步:PPS 方案

FSIN 同步有个硬伤——它只能保证「开始时刻」对齐,但每个摄像头内部的像素时钟是独立的。时间一长,累积误差就出来了。你想想看,如果两个摄像头的晶振精度差 50ppm,一秒钟就能差出 50 微秒。对于高速相机来说,这误差够拍好几帧了。

PPS(Pulse Per Second)方案就是来解决这个问题的。它来自 GPS 或 IEEE 1588 时钟源,每秒输出一个精确的脉冲。摄像头内部用这个脉冲来校准自己的时钟。

具体做法分两步:

  1. 硬件连接:PPS 信号接到每个摄像头的 GPIO 或专用同步输入引脚。
  2. 软件校准:摄像头驱动在 PPS 中断里调整内部时钟计数器。

我记得在做一个车载环视项目时,用了 GPS 的 PPS 信号。四个摄像头分布在车身四周,线缆长度不一样,信号延迟也不同。我当时的做法是:

// 每个摄像头记录 PPS 到达时的本地时间戳
// 主控收集所有时间戳,计算偏移量
// 然后下发补偿值

struct pps_calibration {
    uint64_t local_timestamp;   // 本地时钟计数
    uint64_t pps_timestamp;     // PPS 对应的理想时间
    int32_t  offset_ns;         // 补偿值(纳秒)
};

这样做的好处是,即使摄像头之间没有物理连线,也能通过 PPS 实现亚微秒级的同步。坏处嘛——你得保证 PPS 信号本身的质量。我见过有人用普通 GPIO 模拟 PPS,结果抖动几十微秒,还不如不用。

我的经验:PPS 信号走差分线(比如 RS-422 或 LVDS),抗干扰能力强。单端 PPS 在长距离传输时容易受 EMI 影响。另外,PPS 的上升沿要陡,建议用施密特触发器整形后再进摄像头。

4.3 硬件同步信号设计

FSIN 和 PPS 都是现成的方案。但有时候,项目需求比较特殊,比如需要「交错曝光」——两个摄像头轮流曝光,一个曝光时另一个在读出。这时候就得自己设计同步信号了。

我设计过一套这样的同步方案:

  • 主同步信号(MASTER_SYNC): 50Hz 方波,占空比 50%。
  • 从同步信号(SLAVE_SYNC): 相位偏移 180 度。
  • 曝光使能(EXPOSURE_EN): 高电平有效,控制曝光窗口。

时序关系是这样的:

MASTER_SYNC:  ████░░░░████░░░░████░░░░
SLAVE_SYNC:   ░░░░████░░░░████░░░░████
CAM0_EXP:     ████░░░░░░░░░░████░░░░░░░░
CAM1_EXP:     ░░░░░░████░░░░░░░░░░████░░

你看,CAM0 在 MASTER_SYNC 高电平时曝光,CAM1 在 SLAVE_SYNC 高电平时曝光。两个摄像头永远不会同时曝光,避免了相互干扰。这在红外和可见光双光融合项目中特别有用。

硬件实现上,我用了 CPLD 来做信号发生器。为什么不用 MCU 的定时器?因为 MCU 的定时器输出受中断影响,抖动大。CPLD 纯硬件逻辑,抖动可以控制在 1ns 以内。

设计要点:

  • 所有同步信号必须是同源的,不能各自独立产生。
  • 信号电平要匹配摄像头 I/O 电压(1.8V、2.8V 或 3.3V)。
  • 走线要等长,或者用可编程延迟芯片补偿线缆差异。
  • 预留测试点,方便用示波器量测同步精度。

嗯,说到测试点,我吃过一次亏。当时设计了一块四摄像头板子,同步信号全部走内层,没留测试点。结果调试时发现同步有问题,拿示波器没地方下探头,只能飞线。从那以后,我每个同步信号都强制要求留测试点,哪怕是个 0Ω 电阻的焊盘也行。

4.4 三种方案怎么选?

我整理了一个对比表,方便你决策:

方案 同步精度 硬件复杂度 适用场景
FSIN/STROBE 行级(~10μs) 短距离、帧率不高、摄像头数量少
PPS 时钟同步 亚微秒级(~100ns) 长距离、需要长时间保持同步
自定义硬件信号 纳秒级(~1ns) 特殊时序要求、高速相机、多光谱

我个人习惯是:能用 FSIN 解决的,绝不搞复杂。只有 FSIN 搞不定时,才上 PPS 或自定义方案。毕竟,每多一根线、多一个芯片,就多一个故障点。

最后提醒一句——不管你选哪种方案,一定要在原理图阶段就把同步信号的时序约束写清楚。我曾经见过一个项目,硬件工程师把 FSIN 和 STROBE 接反了,结果软件调了两个月才发现是硬件问题。嗯,这种坑,踩过一次就记住了。