3. 寄存器访问基础

onsemi 图像传感器(如 AR0144、AR0234、AR0821 等)内部有数百到数千个寄存器,用于控制曝光、增益、帧率、输出格式、PLL、测试图形等。主机(SoC/FPGA/MCU)必须通过 I2C 或 SPI 访问这些寄存器。理解协议层、地址映射、读写时序以及页切换机制,是后续所有寄存器调试工作的基础。

一、I2C 与 SPI:两种物理通道的差异

onsemi 传感器通常同时支持 I2C 和 SPI 两种控制接口,二者在电气层和协议层差异明显:

  • I2C:两线(SCL/SDA),7 位从机地址(常见 0x30、0x36、0x3C、0x6C 等,取决于具体型号和 SADDR 引脚电平),支持标准 100 kHz、快速 400 kHz、快速+ 1 MHz。总线上可挂多个器件,靠地址区分。每次读写都要经历 START、从机地址+读写位、ACK、寄存器地址、ACK、数据、ACK、STOP。
  • SPI:四线(CSN、SCK、SDI、SDO),全双工,速率可达数十 MHz。onsemi 传感器 SPI 通常采用 16 位地址 + 8 位数据的帧格式,读写由最高位(R/W 位)区分。SPI 没有 ACK 机制,靠回读校验确认写入成功。

选择原则:初始化阶段寄存器写入量大、要求快,可用 SPI;运行中少量动态调整(如曝光、增益)用 I2C 更省引脚。若两者同时存在,需注意部分型号同一寄存器在两种接口下地址一致,但字节序或位域定义可能不同,务必以对应数据手册为准。

二、寄存器地址映射:16 位地址空间与页结构

onsemi 传感器的寄存器地址通常是 16 位(0x0000–0xFFFF),但 I2C/SPI 单次传输的地址字段往往只有 8 位或 16 位。为覆盖更大的地址空间,芯片内部把地址空间划分为多个“页(Page)”,每页 256 字节(低 8 位为页内偏移,高 8 位为页号)。访问某个寄存器时,需要先写“页选择寄存器”切换到目标页,再访问页内偏移。

典型映射关系(以某型号为例,具体以数据手册为准):

页号地址范围主要内容
0x000x0000–0x00FF核心控制:软复位、PLL、帧率、输出格式
0x010x0100–0x01FF曝光、增益、黑电平
0x020x0200–0x02FFROI、镜像、开窗
0x030x0300–0x03FF测试图形、GPIO、状态

注意:页选择寄存器本身通常位于第 0 页的固定偏移(例如 0x30FE 或 0x301A 等),切换页后该寄存器可能不可见,因此切换前要记住当前页,或每次访问都显式重设页号。

三、读写时序:一次完整访问发生了什么

以 I2C 写一个 16 位地址寄存器为例,典型时序如下:

START
从机地址 + W(0)   → 传感器 ACK
地址高字节        → 传感器 ACK
地址低字节        → 传感器 ACK
数据字节          → 传感器 ACK
STOP

读操作分两段:先写地址(同上,但不发数据),再发 Repeated START + 从机地址 + R(1),然后读取数据字节,主机发 NACK 后 STOP。SPI 则把地址和数据放在同一帧中,CSN 拉低后连续发送 16 位地址(最高位为 R/W),随后在 SCK 边沿采样数据。

关键时序参数:I2C 的 tSU:DAT、tHD:DAT、tLOW、tHIGH 必须满足手册要求;SPI 的 SCK 极性/相位(CPOL/CPHA)必须与传感器一致,onsemi 通常为 CPOL=0、CPHA=0(模式 0)。若时序不满足,会出现写入无效、回读全 0 或全 FF 的现象。

四、页切换与多字节访问

页切换的本质是“先写页寄存器,再访问目标地址”。多字节访问有两种常见形式:

  • 连续地址自增:部分传感器支持地址自动递增,一次传输可连续读写多个相邻寄存器,适合批量初始化。但并非所有型号都支持,需查手册确认。
  • 逐寄存器访问:每次单独发地址+数据,最稳妥,兼容性最好,但速度慢。

实际工程中,初始化序列通常写成“页号 + 地址 + 值”的三元组列表,由驱动按顺序执行。若某次写入后回读不一致,优先检查页号是否被意外改变、地址是否越界、以及 I2C 上拉电阻和总线电容是否导致波形畸变。

onsemi 传感器寄存器访问:页切换与多字节读写路径 主机 SoC / FPGA / MCU I2C 或 SPI 控制器 SCL/SDA 或 SCK/SDI/SDO ① 页选择寄存器 写 Page = 0x01 (位于第 0 页固定偏移) 切换后地址空间变为 0x01xx ② 目标寄存器 地址 0x0136 写/读 数据字节 页内偏移 0x36 ③ 回读校验 读回 0x0136 比对 不一致 → 查页号/时序 多字节访问 连续地址自增:0x0136→0x0137→… 或逐寄存器单独访问 批量初始化推荐自增,兼容性优先逐条 I2C 写时序 START → 从机地址+W → ACK → 地址高字节 → ACK → 地址低字节 → ACK → 数据 → ACK → STOP 常见故障定位: • 回读全 0 / 全 FF → 检查从机地址、上拉电阻、SCK 极性 • 写入无效 → 检查页号是否被覆盖、地址是否越界、tSU/tHD 是否满足

五、实操示例:一次完整的页切换写入

假设要把 0x0136 寄存器写为 0x5A,使用 I2C 从机地址 0x36(7 位),操作序列如下:

// 1. 切换到第 1 页(页选择寄存器位于第 0 页 0x30FE)
I2C_Write(0x36, 0x30, 0xFE, 0x01);

// 2. 写目标寄存器 0x0136 = 0x5A
I2C_Write(0x36, 0x01, 0x36, 0x5A);

// 3. 回读校验
uint8_t val = I2C_Read(0x36, 0x01, 0x36);
if (val != 0x5A) {
    // 检查页号是否仍为 0x01,或重试
}

若使用 SPI,帧格式通常为:CSN 拉低 → 发送 16 位地址(最高位 0 表示写)→ 发送 8 位数据 → CSN 拉高。读操作时最高位为 1,随后在 SCK 下降沿采样 SDO。

工程建议:初始化序列建议按“页号分组”组织,同一页的寄存器连续写完再切页,减少页切换次数。每次切页后,先回读页选择寄存器确认切换成功,再写目标寄存器。对于关键寄存器(如 PLL、输出格式),写入后必须回读校验。
注意:部分 onsemi 传感器在软复位或流模式切换后,页号会自动回到第 0 页。若驱动中缓存了“当前页号”,复位后必须同步清零,否则后续写入会落到错误页,表现为“寄存器写不进去”或“图像异常但无报错”。