2. Sensor硬件接口与电气特性

做Sensor驱动,说白了就是跟硬件接口打交道。你写的代码最终要控制物理层的信号,电源没给对,时序没卡准,Sensor压根不工作。我刚开始调Sensor时,就吃过上电时序的亏,板子一上电,Sensor纹丝不动,查了三天才发现是DVDD比AVDD早来了2ms。嗯,这种坑踩过一次就记住了。

2.1 MIPI CSI-2物理层:数据是怎么飞起来的

CSI-2是Camera和SoC之间的图像传输通道。物理层目前主流是D-PHY,C-PHY也在高端平台慢慢铺开。说白了,D-PHY是差分信号,C-PHY是三相信号,两者不兼容,选型时得看SoC支持哪种。

核心要点:CSI-2物理层只管把像素数据从Sensor搬到AP,不负责控制Sensor寄存器。控制走I2C/SPI,数据走MIPI,两条线各干各的。

2.1.1 D-PHY:差分对,简单可靠

D-PHY用一对差分线(Dp/Dn)传数据,另一对传时钟。我习惯把时钟对叫CLK,数据对叫DATA,一个CLK Lane可以配1~4个DATA Lane。分辨率越高,需要的Lane越多。

  • 速率范围:80 Mbps ~ 2.5 Gbps per Lane
  • 信号电平:差分摆幅200 mV ~ 1.2 V,共模电压200 mV左右
  • 工作模式:HS(高速)传数据,LP(低功耗)传控制
  • 状态机:LP-11 → LP-01 → LP-00 进入HS,HS结束后回到LP-11

D-PHY的HS模式是电流驱动,LP模式是电压驱动。我在调试时遇到过一个问题:LP模式下Sensor能正常识别,但一切到HS就丢包。后来发现是PCB上CLK和DATA的等长没做好,差了300mil,导致采样窗口偏移。嗯,Layout的坑,驱动工程师也得懂一点。

2.1.2 C-PHY:三相线,带宽更高

C-PHY不用差分对,改用三根线(A/B/C),每根线有三种电平状态。三根线组合起来,一个Symbol能传2.28 bit数据。你想想看,同样的线数,C-PHY的带宽比D-PHY高不少。

参数 D-PHY C-PHY
物理线数 2 per Lane(Dp/Dn) 3 per Trio(A/B/C)
每线速率 2.5 Gbps max 2.5 Gsym/s
等效带宽 2.5 Gbps per Lane ~5.7 Gbps per Trio
信号类型 差分 三相电平
兼容性 广泛 高端SoC

C-PHY的优点是带宽高、EMI低,但协议复杂,调试工具也少。我个人建议,除非SoC强制要求C-PHY,否则先用D-PHY,成熟稳定,示波器一看就知道信号对不对。

调试小技巧:用示波器抓D-PHY的HS信号时,把探头设为差分模式,触发条件设成LP-11→LP-00的跳变。这样能准确抓到HS的起始位置,方便看眼图。

2.2 I2C/SPI控制接口:怎么跟Sensor说话

Sensor的寄存器读写,99%用I2C,少数用SPI。I2C只需要两根线(SCL/SDA),SPI需要四根(SCLK/MOSI/MISO/CS)。我做过一个项目,Sensor同时支持I2C和SPI,通过一个引脚电平选择。嗯,这种设计挺常见,选型时注意看Datasheet。

2.2.1 I2C:两根线,慢但够用

I2C的标准速率是100 kHz,快速模式400 kHz,高速模式3.4 MHz。Sensor寄存器读写量不大,400 kHz完全够用。我习惯把I2C速率设在400 kHz,再高容易受PCB走线影响。

// I2C写Sensor寄存器示例
int sensor_write_reg(uint8_t slave_addr, uint16_t reg_addr, uint8_t data) {
    uint8_t buf[3];
    buf[0] = (reg_addr >> 8) & 0xFF;  // 高字节地址
    buf[1] = reg_addr & 0xFF;         // 低字节地址
    buf[2] = data;                    // 写入数据
    return i2c_master_write(slave_addr, buf, 3);
}

这里有个坑:有些Sensor的寄存器地址是8位,有些是16位。我遇到过Sensor手册写的是16位地址,但实际只认低8位,高8位忽略。调试时先读一下Device ID,确认地址格式对不对。

2.2.2 SPI:四根线,快且灵活

SPI适合需要批量读写Sensor的场景,比如OTA升级固件。SPI速率可以跑到几十MHz,但Sensor内部逻辑不一定跟得上。我建议先按10 MHz起步,稳定后再往上提。

// SPI读Sensor寄存器示例
int sensor_spi_read(uint8_t reg_addr, uint8_t *data) {
    uint8_t tx_buf[2];
    tx_buf[0] = 0x80 | reg_addr;  // 读命令 + 地址
    tx_buf[1] = 0x00;             // dummy byte
    spi_transfer(tx_buf, data, 2);
    return 0;
}

注意:SPI的极性(CPOL)和相位(CPHA)必须和Sensor匹配。我见过有人把CPOL设反了,读回来的数据全是0xFF。查了半天,最后发现是模式0和模式3的区别。

2.3 电源管理:AVDD/DVDD/IOVDD

Sensor一般需要三路电源:AVDD(模拟)、DVDD(数字核心)、IOVDD(IO接口)。这三路电压值因Sensor型号而异,但有个规律:AVDD最高(2.8V常见),DVDD最低(1.2V或1.8V),IOVDD和SoC的IO电压对齐(1.8V或2.8V)。

电源轨 典型电压 电流需求 纹波要求
AVDD 2.8V 50~200 mA < 10 mVpp
DVDD 1.2V / 1.8V 30~100 mA < 20 mVpp
IOVDD 1.8V / 2.8V 10~50 mA < 30 mVpp

AVDD的纹波要求最严,因为模拟电路对电源噪声敏感。我遇到过Sensor输出图像有横纹,用示波器一看,AVDD上有200 mV的开关噪声。后来在电源输出端加了个10 μF + 0.1 μF的去耦电容,纹波降到5 mV,图像立马干净了。

个人习惯:Layout时AVDD走线单独铺铜,远离DVDD和IOVDD。电源入口放一个磁珠,隔离数字噪声。Sensor的每个电源引脚旁边都放一个0.1 μF电容,位置越近越好。

2.4 上电时序:顺序错了,Sensor不干活

上电时序是驱动调试的第一步,也是最容易出问题的地方。Sensor Datasheet里会给出一个时序图,标明AVDD、DVDD、IOVDD、MCLK、RST、I2C的先后顺序。我见过最严格的时序要求是:AVDD先上,DVDD后上,间隔至少1 ms。

// 典型上电时序代码(伪代码)
void sensor_power_on(void) {
    // 1. 先上AVDD
    regulator_enable(REG_AVDD, 2800000);  // 2.8V
    delay_ms(2);  // 等待稳定

    // 2. 再上DVDD
    regulator_enable(REG_DVDD, 1200000);  // 1.2V
    delay_ms(1);

    // 3. 最后上IOVDD
    regulator_enable(REG_IOVDD, 1800000); // 1.8V
    delay_ms(1);

    // 4. 提供MCLK
    clk_enable(MCLK, 24000000);  // 24 MHz
    delay_ms(1);

    // 5. 释放RST
    gpio_set_level(RST_PIN, 1);
    delay_ms(10);  // 等待Sensor初始化

    // 6. 开始I2C通信
    i2c_init();
}

我曾经遇到一个Sensor,上电时序要求DVDD不能比AVDD早超过5 ms。但板子上的电源芯片启动时间不一致,DVDD总是比AVDD早10 ms。结果Sensor上电后I2C地址对不上,读Device ID全是0xFF。后来在DVDD路径上加了个RC延时,把时序调对了。

避坑指南:上电时序不要只看Datasheet的典型值,要看最小值和最大值。比如AVDD到DVDD的延迟,典型值是1 ms,但最小值可能是0 ms,最大值可能是5 ms。按典型值设计,万一电源芯片有偏差,Sensor就可能不工作。

2.5 知识结构总览

下面这张图把本章的核心知识点串起来了。从物理层到控制接口,再到电源和时序,每一步都是Sensor正常工作的前提。

Sensor硬件接口与电气特性知识结构图 Sensor硬件接口与电气特性知识结构 Sensor硬件接口 MIPI CSI-2 物理层 I2C / SPI 控制接口 电源管理 上电时序 D-PHY 差分对 C-PHY 三相线 I2C 协议 SPI 协议 AVDD DVDD IOVDD 上电顺序 时序参数 核心原则:物理层决定带宽,控制接口决定可配置性,电源和时序决定Sensor能否正常工作 关键参数速查 D-PHY: 80M~2.5Gbps/Lane I2C: 100k~3.4MHz AVDD纹波: <10mVpp ⚠ 常见坑:上电时序不对、I2C地址错误、电源纹波过大导致图像异常

这张图把本章的知识点分成了四个块:物理层、控制接口、电源、时序。每个块下面又有子节点,方便你快速定位问题。调试时遇到Sensor不工作,先按这个结构排查:电源给了吗?时序对吗?I2C能通吗?MIPI信号正常吗?一步步来,问题总能找到。