2. 图像传感器接口与数据采集:MIPI、LVDS 与 FPGA 解串实战
好,我们直接进入正题。内窥镜图像采集,第一步就是把传感器那头的高速数据稳稳地接进来。这活儿看着简单,其实坑不少。今天我就把 MIPI 和 LVDS 这两个最常见的接口,以及怎么用 FPGA 把它们“吃”进来,掰开了揉碎了讲清楚。
2.1 为什么是高速串行接口?
你想想看,一个 1080P 的图像传感器,30fps,每个像素 10bit。算一下带宽:1920×1080×30×10 ≈ 622Mbps。这还只是单路。要是用传统的并行接口,几十根线拉来拉去,PCB 布线就成了噩梦,信号完整性也根本保证不了。
所以,业界普遍采用串行接口。说白了,就是把并行数据串行化,用一对差分线(D+ / D-)来传输。这样线少、干扰小、速率高。内窥镜里最常用的就是 MIPI 和 LVDS。
核心区别一句话:LVDS 是纯物理层标准,只管信号怎么传;MIPI 则定义了完整的协议栈,从物理层到应用层都管了。内窥镜里,老一点的 sensor 多用 LVDS,新的基本都转向 MIPI 了。
2.2 LVDS 接口:简单可靠的老将
LVDS,Low-Voltage Differential Signaling,低压差分信号。它的原理很简单:用一对线上的电压差(约 350mV)来表示 0 和 1。功耗低,噪声小。
在图像传感器里,LVDS 通常以“通道+时钟”的方式出现。比如 4 对数据线 + 1 对时钟线。每个时钟周期,每条数据线传 1 bit。所以 4 通道的 LVDS,一个时钟周期就能传 4 bit。
FPGA 怎么接?
FPGA 接收 LVDS,最直接的办法是用硬核。Xilinx 的器件里,有 ISERDES(串并转换器)这个硬核。我习惯直接例化它,省事又稳定。
// 一个简单的 LVDS 解串示例(7系列 FPGA)
// 假设:1:7 解串,即每个时钟周期传 7 bit 数据
ISERDESE2 #(
.DATA_WIDTH(7), // 串行数据宽度
.DATA_RATE("DDR"), // 双沿采样
.INTERFACE_TYPE("NETWORKING"),
.NUM_CE(1)
) iserdes_inst (
.Q1(q1), .Q2(q2), .Q3(q3), .Q4(q4),
.Q5(q5), .Q6(q6), .Q7(q7), .Q8(),
.SHIFTOUT1(), .SHIFTOUT2(),
.BITSLIP(bitslip), // 用于字对齐
.CE1(1'b1), .CE2(1'b1),
.CLK(clk_div), // 分频后的并行时钟
.CLKB(~clk_div), // 互补时钟
.CLKDIV(clk_div), // 并行时钟
.D(lvds_data_p), // 差分数据正端
.DDLY(),
.RST(reset),
.SHIFTIN1(), .SHIFTIN2()
);
个人经验:LVDS 解串最头疼的是“字对齐”。因为串行数据没有帧头,你不知道哪 7 个 bit 是一个像素。我一般会在 sensor 端插入一个特定的同步码(比如 0x7F),然后在 FPGA 里用 BITSLIP 功能滑动窗口去匹配。找到同步码后,锁定对齐状态。这步做不好,图像就是花的。
2.3 MIPI CSI-2:现代内窥镜的主流选择
MIPI,Mobile Industry Processor Interface,移动产业处理器接口。CSI-2 是它的摄像头接口标准。内窥镜里,MIPI 已经成了事实标准。
MIPI 的物理层叫 D-PHY。它用一对差分线,但比 LVDS 复杂。它支持两种模式:
- 高速模式(HS):用于传输图像数据,速率可达 2.5Gbps/lane。信号摆幅小(约 200mV)。
- 低功耗模式(LP):用于传输控制命令,速率低,但功耗极低。信号摆幅大(约 1.2V)。
MIPI 的协议层定义了数据包格式。每个包有“短包”(用于帧同步、行同步)和“长包”(用于像素数据)。
避坑指南:我曾经在一个项目中,MIPI 的 LP 模式老是出问题。sensor 发送的 LP 命令,FPGA 这边收不到。查了好久,发现是 PCB 上 MIPI 线的阻抗没控制好。LP 模式对阻抗不敏感,但 HS 模式要求 100Ω 差分阻抗。我后来在 layout 时严格按 100Ω 走线,问题就解决了。记住:MIPI 的 HS 模式,对 PCB 走线要求极高。
2.4 FPGA 如何接收 MIPI?硬核 vs 软核
FPGA 接收 MIPI,有两种主流方案:
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 硬核方案(GTP/GTX) | 稳定、速率高、功耗低、集成度高 | 需要 license、占用专用引脚、灵活性稍差 | 量产产品、高性能内窥镜 |
| 软核方案(逻辑实现) | 灵活、无需额外成本、可定制 | 速率受限(一般 < 1Gbps)、占用大量逻辑资源 | 原型验证、低速率 sensor、学习研究 |
我个人习惯:只要项目预算允许,我肯定用硬核。GTP/GTX 是专门为高速串行通信设计的,内部有 PLL、CDR(时钟数据恢复)、串并转换等完整模块。你只需要配置好参数,它就能稳定工作。软核方案,说白了就是用 FPGA 的普通逻辑去模拟高速收发器。速率一高,时序就很难收敛。
下面是一个用 Xilinx 7 系列 GTP 接收 MIPI 的简化配置思路:
// GTP 配置要点(以 4 lane MIPI 为例)
// 1. 线速率:假设 sensor 输出 1.2Gbps/lane
// 2. 参考时钟:外部提供 100MHz 差分时钟
// 3. 协议:选择 "RAW10" 或 "RAW12" 模式
// 4. 数据对齐:启用 "comma detect" 功能,用 K28.5 字符对齐
// 关键参数设置(Vivado 中)
// Line Rate: 1200 Mbps
// Reference Clock: 100 MHz
// TX/RX: 仅 RX
// Data Width: 20 bit (DDR 模式,双沿采样)
// Internal Data Width: 40 bit (2 个时钟周期合并)
注意:MIPI 的 D-PHY 和 FPGA 的 GTP/GTX 在电气特性上并不完全兼容。D-PHY 的 HS 模式是 200mV 摆幅,而 GTP 通常需要 400-800mV。所以,中间往往需要加一个电平转换芯片(比如 TI 的 SN65LVDS 系列)。我见过有人直接连,结果烧了 FPGA 的 bank。千万别省这个芯片。
2.5 数据采集的完整流程
不管用 LVDS 还是 MIPI,FPGA 内部的数据采集流程都差不多:
- 物理层接收:通过硬核或软核,把串行数据转成并行数据。
- 字对齐:找到数据的边界,确保每个并行字是正确的。
- 协议解析:解析 MIPI 的包格式,或者 LVDS 的同步码,提取出有效的像素数据。
- 数据重组:把像素数据按 Bayer 格式(或 RGB)排列好,存入 FIFO。
- 后续处理:交给 ISP 模块做去噪、白平衡、色彩校正等。
嗯,这里要特别强调一下“数据重组”。内窥镜的 sensor 输出通常是 Bayer 格式,每个像素只有一种颜色(R、G 或 B)。FPGA 需要把这些数据按 2×2 的 Bayer 矩阵重新排列,才能交给后面的 ISP 做插值。这个排列顺序错了,图像颜色就全乱了。
我的调试技巧:第一次调通 MIPI 接收后,别急着看图像。先抓一段原始数据,用 MATLAB 或 Python 解析一下,看看 Bayer 格式对不对。我曾经花了两天时间调图像颜色,最后发现是 Bayer 顺序搞反了。从那以后,我每次都会先做这个验证。
2.6 总结与建议
图像传感器接口这块,说白了就是“物理层+协议层”的博弈。LVDS 简单,适合低分辨率、低帧率的场景。MIPI 复杂,但性能上限高,是现代内窥镜的首选。
对于 FPGA 工程师,我的建议是:
- 优先用硬核。 GTP/GTX 是经过验证的,别自己造轮子。
- 重视 PCB 设计。 高速信号对走线长度、阻抗、过孔数量都非常敏感。我见过太多因为 PCB 问题导致 MIPI 无法锁定的案例。
- 做好调试接口。 在 FPGA 里留一个 ILA(集成逻辑分析仪)的探针,方便抓取 MIPI 的原始数据。这能帮你快速定位问题。
下一章,我们会讲怎么把采集到的图像数据,通过 FPGA 做预处理。到时候再聊。