第二章 图像传感器接口与数据采集:MIPI CSI-2协议基础、Sensor配置(I2C)、RAW数据格式解析

各位同学,欢迎来到第二章。上一章我们聊了FPGA图像加速的整体架构,这一章咱们要扎进一个非常关键的环节——怎么把图像数据从传感器里“拽”出来。

说白了,图像处理的第一步就是采集。传感器采集到的原始数据,通过MIPI接口传过来,FPGA得把它稳稳接住,然后解析成我们能处理的格式。这里面有三个核心知识点:MIPI CSI-2协议、I2C配置传感器、RAW数据格式。咱们一个一个来啃。

2.1 MIPI CSI-2协议基础

MIPI CSI-2,全称是Camera Serial Interface 2。它是移动设备领域最主流的摄像头接口标准。为什么用它?因为速度快、引脚少、抗干扰强。

我个人习惯把MIPI接口理解成一条“高速公路”。传感器是发车端,FPGA是收车端。数据在差分对(D-PHY)上跑,时钟和数据分开传输。

2.1.1 物理层:D-PHY

D-PHY是MIPI的物理层标准。它使用差分信号传输,一对线传时钟,一对或多对线传数据。每一对线都是P和N两根,电压摆幅很小,所以功耗低、速率高。

我在项目中遇到过一个问题:某款传感器输出4 lane MIPI,速率高达1.2Gbps/lane。FPGA的Bank电压没配好,导致眼图质量很差。后来查了半天,发现是PCB走线阻抗没控制好。嗯,这里要注意:MIPI走线必须严格按100欧姆差分阻抗设计。

参数 典型值 说明
差分阻抗 100Ω ±10% PCB设计关键
电压摆幅 200mV (LP模式) 低功耗模式
数据速率 80Mbps ~ 2.5Gbps/lane 取决于版本

2.1.2 协议层:包结构

MIPI CSI-2的数据是以“包”为单位传输的。每个包分为短包和长包。短包主要传帧同步、行同步等控制信息;长包传像素数据。

你想想看,FPGA怎么知道一帧图像从哪里开始?靠的就是短包里的帧起始码(FS)和帧结束码(FE)。

我曾经调试一个摄像头,图像一直花屏。用示波器抓MIPI信号,发现帧起始码后面紧跟着的数据长度不对。后来发现是传感器的配置寄存器写错了,导致输出的行长度和实际像素数不匹配。避坑指南:一定要先确认传感器的输出格式和分辨率,再配置FPGA的接收端。

核心要点:MIPI CSI-2的包结构是:短包(8字节)或长包(包头4字节 + 数据 + 包尾2字节)。FPGA接收时,先检测同步头,再解析包类型。

2.2 Sensor配置(I2C)

传感器不会自己工作。你得通过I2C总线告诉它:输出多大分辨率、多少帧率、什么数据格式。这就是传感器配置。

I2C是一种两线制串行总线:SCL(时钟)和SDA(数据)。传感器作为从设备,FPGA作为主设备。每个传感器都有一个唯一的设备地址,通常是7位或10位。

2.2.1 I2C时序

I2C的时序其实不复杂。起始条件:SCL高电平时,SDA从高变低。停止条件:SCL高电平时,SDA从低变高。数据传输:SCL低电平时改变SDA,SCL高电平时采样SDA。

我建议初学者用状态机来实现I2C控制器。状态机分几个状态:IDLE、START、SEND_ADDR、SEND_REG、SEND_DATA、STOP。每个状态处理一个字节的传输。

// I2C写操作示例(Verilog伪代码)
always @(posedge clk) begin
    case(state)
        IDLE: begin
            if(start) begin
                sda_out <= 0;  // 起始条件
                state <= SEND_ADDR;
            end
        end
        SEND_ADDR: begin
            // 发送7位设备地址 + 写位(0)
            // 等待ACK
            state <= SEND_REG;
        end
        SEND_REG: begin
            // 发送寄存器地址
            state <= SEND_DATA;
        end
        SEND_DATA: begin
            // 发送配置数据
            state <= STOP;
        end
        STOP: begin
            sda_out <= 1;  // 停止条件
            state <= IDLE;
        end
    endcase
end

小技巧:I2C的速率通常有100kHz(标准模式)和400kHz(快速模式)。传感器配置一般用100kHz就够了。速率太高反而容易出错,尤其是PCB走线较长时。

2.2.2 常见传感器配置流程

以索尼IMX系列传感器为例,配置流程一般是:

  1. 上电后等待传感器稳定(约10ms)
  2. 复位传感器(写复位寄存器)
  3. 配置PLL(设置主时钟频率)
  4. 配置输出分辨率(如1920x1080)
  5. 配置输出格式(如RAW10)
  6. 配置帧率(通过调整行消隐和帧消隐)
  7. 启动输出(写启动寄存器)

我记得有一次,传感器死活不出图。用逻辑分析仪抓I2C波形,发现ACK信号一直没回来。查了传感器手册,发现它的设备地址是0x6C(7位),但我写成了0xD8(8位)。嗯,这里要注意:I2C设备地址是7位,但写操作时左移一位,最低位补0。

2.3 RAW数据格式解析

传感器输出的原始数据,通常叫RAW格式。它没有经过任何处理,每个像素只保留一个颜色分量。常见的RAW格式有RAW8、RAW10、RAW12、RAW14等。数字表示每个像素的位宽。

为什么用RAW?因为它是传感器最原始的数据,保留了最多的信息。后续的ISP处理(去马赛克、白平衡、伽马校正等)都基于RAW数据。

2.3.1 Bayer模式

大多数彩色传感器使用Bayer滤色阵列。每个像素只采集红、绿、蓝中的一个颜色。常见的Bayer模式有RGGB、BGGR、GRBG、GBRG。其中RGGB是最常见的:第一行是R、G、R、G...,第二行是G、B、G、B...

你想想看,如果传感器输出的是RAW10格式,每个像素占10位。但FPGA内部通常以8位或16位为单位处理数据。所以我们需要做位拼接。

数据对齐:RAW10数据在MIPI传输时,4个像素打包成5个字节(40位)。FPGA接收后,需要拆包还原成每个像素10位的数据。

2.3.2 RAW数据在FPGA中的处理

FPGA接收MIPI数据后,首先做串并转换,把高速串行数据转成并行数据。然后根据传感器的输出格式,解析出每个像素的值。

我建议用FIFO来缓冲数据。MIPI接收端的数据速率和后续处理模块的速率可能不一致,FIFO可以平滑这个差异。

// RAW10数据拆包示例
// 输入:5字节(40位),包含4个RAW10像素
// 输出:4个10位像素
assign pixel0 = data_in[9:0];
assign pixel1 = data_in[19:10];
assign pixel2 = data_in[29:20];
assign pixel3 = data_in[39:30];

注意:不同传感器的RAW数据排列方式可能不同。有的传感器先输出高字节,有的先输出低字节。一定要看传感器手册的“Data Format”章节。

2.4 本章知识体系

为了让大家更直观地理解本章的知识结构,我画了一张图。它展示了从传感器到FPGA的数据流,以及每个环节的关键点。

图像传感器接口与数据采集 - 知识体系 图像传感器 CMOS/CCD Bayer阵列 I2C配置 分辨率/帧率/格式 MIPI CSI-2 D-PHY差分传输 包结构/同步码 FPGA接收 串并转换 数据对齐 RAW数据解析 RAW8/10/12/14 ISP处理 去马赛克/白平衡 数据流方向:传感器 → MIPI → FPGA → RAW解析 → ISP 关键点: 1. MIPI D-PHY:差分信号,100Ω阻抗匹配 2. I2C配置:设备地址、寄存器映射、时序 3. RAW格式:Bayer模式、位宽、数据对齐 4. FPGA接收:串并转换、FIFO缓冲、包解析

这张图把整个数据流串起来了。从传感器开始,经过MIPI传输,FPGA接收并解析RAW数据,最后交给ISP处理。每个环节都有它的技术难点,但只要你理解了协议和时序,就能搞定。

好了,这一章的内容就到这里。MIPI协议、I2C配置、RAW格式,这三个知识点是图像采集的基石。下一章我们会深入FPGA内部的图像处理流水线,到时候这些知识都会用上。

个人建议:初学者可以先从模拟I2C配置开始,用逻辑分析仪抓波形,理解时序。然后再上手MIPI接收,用FPGA的IP核或者自己写代码。一步一步来,别急。

可可精品资料库