4. Sensor 寄存器配置基础:I2C/SPI 通信协议、寄存器地址与数据格式、常用寄存器组
Sensor 的寄存器配置是图像传感器工作的“大脑”。所有曝光时间、增益大小、帧率、输出格式等行为,都通过读写内部寄存器实现。本章聚焦于物理层通信协议(I2C/SPI)、寄存器寻址与数据格式,以及最核心的增益、曝光、帧长、行长寄存器组。
4.1 I2C 与 SPI 通信协议对比
Sensor 与 ISP/主控之间的控制通道通常采用 I2C 或 SPI。两者在引脚数、速率、拓扑结构上差异明显,选型需根据项目需求权衡。
| 特性 | I2C(Inter-Integrated Circuit) | SPI(Serial Peripheral Interface) |
|---|---|---|
| 引脚数 | 2 线:SCL(时钟)、SDA(数据) | 4 线:SCLK、MOSI、MISO、CS |
| 拓扑 | 多主多从,总线式 | 一主多从,片选独立 |
| 速率 | 标准 100kHz / 快速 400kHz / 高速 3.4MHz | 通常 10MHz ~ 50MHz,甚至更高 |
| 寻址方式 | 7 位或 10 位设备地址 + 寄存器地址 | 片选信号 + 无设备地址 |
| 数据方向 | 半双工,主从双向共用 SDA | 全双工,MOSI/MISO 独立 |
| 抗干扰 | 开漏输出,上拉电阻,适合短距离 | 推挽输出,信号完整度更好 |
| 典型场景 | 手机摄像头、消费类 Sensor | 工业相机、高帧率 Sensor、多 Sensor 同步 |
4.1.1 I2C 读写时序
I2C 写操作流程:主设备发送起始条件 → 设备地址 + 写位 → 从设备 ACK → 寄存器高字节地址 → ACK → 寄存器低字节地址 → ACK → 数据字节 → ACK → 停止条件。
// I2C 写 2 字节数据到 16 位地址寄存器示例(伪代码)
uint8_t write_buf[4];
write_buf[0] = (reg_addr >> 8) & 0xFF; // 地址高字节
write_buf[1] = reg_addr & 0xFF; // 地址低字节
write_buf[2] = (data >> 8) & 0xFF; // 数据高字节
write_buf[3] = data & 0xFF; // 数据低字节
i2c_master_write(dev_addr, write_buf, 4);
4.1.2 SPI 读写时序
SPI 写操作:CS 拉低 → 在 SCLK 上升沿发送 8 位命令(通常写命令为 0x02)→ 发送 16 位寄存器地址 → 发送 N 字节数据 → CS 拉高。
// SPI 写 2 字节到 16 位地址寄存器示例(伪代码)
uint8_t spi_tx[5];
spi_tx[0] = 0x02; // 写命令
spi_tx[1] = (reg_addr >> 8) & 0xFF; // 地址高字节
spi_tx[2] = reg_addr & 0xFF; // 地址低字节
spi_tx[3] = (data >> 8) & 0xFF; // 数据高字节
spi_tx[4] = data & 0xFF; // 数据低字节
spi_cs_low();
spi_transfer(spi_tx, 5);
spi_cs_high();
4.2 寄存器地址与数据格式
Sensor 寄存器地址长度通常为 8 位或 16 位,数据宽度多为 8 位、16 位或 32 位。理解地址映射规则和数据排列方式,是正确配置 Sensor 的前提。
4.2.1 地址映射规则
- 8 位地址空间: 常见于低分辨率 Sensor,寄存器数量少,地址范围 0x00 ~ 0xFF。
- 16 位地址空间: 主流 Sensor 采用,地址范围 0x0000 ~ 0xFFFF,支持大量功能寄存器。
- 页切换(Page): 部分 Sensor 将寄存器分组到不同页,通过页选择寄存器切换访问。
// 页切换示例(以 OV5640 为例)
// 切换到页 0
i2c_write(0x3008, 0x82); // 软件复位
i2c_write(0x3100, 0x01); // 页选择寄存器 = 0x01 表示页 0
// 切换到页 1
i2c_write(0x3100, 0x05); // 页选择寄存器 = 0x05 表示页 1
4.2.2 数据格式与位域操作
寄存器数据通常以 大端序(Big-Endian) 存储,即高字节在前、低字节在后。多字节寄存器需要按位域拆分,避免误写保留位。
| 位域 | 寄存器地址 | 位 [7:4] | 位 [3:0] |
|---|---|---|---|
| 增益控制 | 0x3503 | 增益模式(0x0=模拟,0x1=数字) | 保留(写 0) |
| 曝光高字节 | 0x3500 | 曝光时间高 8 位 | |
| 曝光低字节 | 0x3501 | 曝光时间低 8 位 | |
// 读-改-写示例:设置增益模式为数字增益,保留其他位
uint8_t reg_val = i2c_read(0x3503);
reg_val &= 0x0F; // 清除高 4 位
reg_val |= (0x01 << 4); // 设置位 [7:4] = 0x1(数字增益模式)
i2c_write(0x3503, reg_val);
4.3 常用寄存器组详解
AE 联调中最常操作的寄存器组包括:增益、曝光时间、帧长(VTS)、行长(HTS)。这四个参数直接决定图像亮度和帧率。
4.3.1 增益寄存器(Gain)
增益分为模拟增益(Analog Gain)和数字增益(Digital Gain)。模拟增益在像素读出前放大信号,噪声较低;数字增益在 ADC 之后放大,会放大噪声。
- 模拟增益: 通常以 0.1dB 或 0.3dB 步进,范围 1x ~ 16x。
- 数字增益: 范围 1x ~ 8x,步进 0.125x。
- 全局增益: 部分 Sensor 提供组合增益寄存器,自动分配模拟/数字比例。
// 设置模拟增益为 2x(假设增益寄存器 0x3503 步进为 0.1dB)
// 2x = 6.02dB → 6.02 / 0.1 = 60 → 0x3C
i2c_write(0x3503, 0x3C);
4.3.2 曝光时间寄存器(Exposure / Shutter)
曝光时间通过控制电子快门的行数(Line Count)实现。曝光行数 × 行时间 = 实际曝光时间。
- 曝光行数寄存器: 通常为 16 位或 20 位,地址连续。
- 最大曝光行数: 受帧长(VTS)限制,通常 ≤ VTS - 4(预留消隐行)。
- 最小曝光行数: 受 Sensor 最小消隐要求限制,通常 ≥ 1 行。
// 设置曝光行数为 1000 行(16 位寄存器 0x3500-0x3501)
uint16_t exposure_lines = 1000;
i2c_write(0x3500, (exposure_lines >> 8) & 0xFF); // 高字节
i2c_write(0x3501, exposure_lines & 0xFF); // 低字节
4.3.3 帧长寄存器(VTS / Vertical Total Size)
帧长决定一帧图像的总行数,包括有效行和垂直消隐行。帧长直接影响帧率:帧率 = PCLK / (HTS × VTS)。
- VTS 寄存器: 通常为 16 位,地址如 0x320E-0x320F。
- 调整影响: 增大 VTS 会降低帧率,但可增加最大曝光行数。
- AE 联动: 当曝光行数接近 VTS 时,AE 算法需考虑是否扩展 VTS 以增加曝光空间。
// 设置帧长为 1500 行
uint16_t vts = 1500;
i2c_write(0x320E, (vts >> 8) & 0xFF);
i2c_write(0x320F, vts & 0xFF);
4.3.4 行长寄存器(HTS / Horizontal Total Size)
行长决定一行像素的总数,包括有效像素和水平消隐。行长通常固定,但部分 Sensor 支持调整以微调帧率。
- HTS 寄存器: 通常为 16 位,地址如 0x320C-0x320D。
- 固定场景: 多数 Sensor 在初始化时设定 HTS,AE 联调中不修改。
- 动态场景: 高帧率模式可能需要减小 HTS 以压缩行时间。
// 设置行长为 2200 像素(含消隐)
uint16_t hts = 2200;
i2c_write(0x320C, (hts >> 8) & 0xFF);
i2c_write(0x320D, hts & 0xFF);
4.4 常用寄存器组关系图
4.5 实战配置流程
- 初始化通信: 配置 I2C/SPI 控制器速率、引脚、模式。
- 读取 Sensor ID: 验证通信正常,读取芯片 ID 寄存器(如 0x300A-0x300B)。
- 写入初始化序列: 按 datasheet 写入 PLL、分辨率、输出格式等寄存器。
- 设置帧长和行长: 确定目标帧率,计算 VTS 和 HTS 并写入。
- 设置初始曝光和增益: 写入默认曝光行数和增益值。
- 启动视频流: 写入启动寄存器(如 0x0100 = 0x01)。
- AE 联调: 根据亮度反馈,动态调整曝光和增益寄存器。