3、Sensor上电时序与硬件初始化:DVDD/AVDD/IOVDD电源域、Reset/Standby引脚控制、MCLK时钟配置、PLL锁相环设置、硬件初始化序列编写
Sensor 上电,不是插上电就完事的。
很多新手工程师,拿到模组就往板子上怼。结果图像出不来,或者花屏、闪屏。查半天,发现是上电时序搞反了。我当年也踩过这个坑,烧坏过一个模组,心疼了好几天。
说白了,Sensor 是个精密的模拟+数字混合器件。它需要按照严格的“剧本”来唤醒。这个剧本,就是硬件初始化序列。
3.1 电源域:DVDD、AVDD、IOVDD
一个典型的 Sensor,至少需要三路电源:
| 电源域 | 典型电压 | 供电对象 | 电流需求 |
|---|---|---|---|
| DVDD(数字核心) | 1.2V / 1.8V | 数字逻辑、PLL 数字部分 | 几十 mA |
| AVDD(模拟) | 2.8V / 3.3V | 像素阵列、模拟放大器、ADC | 100mA ~ 300mA |
| IOVDD(I/O 接口) | 1.8V / 2.8V | MIPI、I2C、GPIO 接口电平 | 十几 mA |
核心原则:先供核心,再供模拟,最后供 I/O。或者严格遵循 Datasheet 的时序图。
我习惯的做法是:DVDD 先上 → AVDD 跟上 → IOVDD 最后上。为什么?因为数字核心先稳定,模拟电路后启动,I/O 接口最后才去跟主控握手。反过来,如果 IOVDD 先上,Sensor 的 I2C 接口已经带电,但内部逻辑还没跑起来,容易产生总线锁死或漏电。
注意:不同型号的 Sensor,上电顺序可能完全相反。有的要求 AVDD 先于 DVDD。务必以 Datasheet 的时序图为准,不要凭经验硬套。
3.2 Reset 与 Standby 引脚控制
电源稳定后,Sensor 还处于“休眠”状态。我们需要通过硬件引脚把它叫醒。
- Reset 引脚(复位): 低电平有效。拉低至少 1ms(具体看规格书),然后释放。Sensor 内部寄存器会恢复到默认值。
- Standby 引脚(待机): 有些 Sensor 叫 PWDN(Power Down)。高电平进入待机,低电平正常工作。这个引脚用来控制 Sensor 的功耗模式。
我遇到过一个问题:Reset 释放后,马上就去写 I2C 寄存器,结果写不进去。为什么?因为 Sensor 内部 PLL 还没锁定,I2C 接口虽然物理上通了,但逻辑上还没准备好。后来我加了 10ms 的延时,问题解决。
经验值:Reset 释放后,建议等待 5~20ms 再开始 I2C 通信。这个时间足够内部振荡器起振和 PLL 锁定。
3.3 MCLK 时钟配置
Sensor 需要外部提供主时钟(MCLK),才能开始工作。这个时钟通常来自主控 SoC 的 GPIO 或专用时钟输出引脚。
- 频率: 常见的有 6MHz、12MHz、24MHz、27MHz。具体看 Sensor 的 Datasheet。
- 精度: 要求 ±1% 以内。如果时钟不准,输出的图像帧率会漂移,甚至 PLL 无法锁定。
- 波形: 方波,占空比 45%~55%。
我建议:MCLK 必须在 IOVDD 稳定之后、Reset 释放之前提供。有些 Sensor 在 Reset 释放瞬间会检测 MCLK 是否存在,如果没检测到,会进入错误状态。
3.4 PLL 锁相环设置
Sensor 内部有一个 PLL,用来把外部 MCLK 倍频到内部所需的高频时钟。比如,MCLK 是 24MHz,PLL 倍频后得到 720MHz 的像素时钟。
PLL 的配置通常通过 I2C 寄存器完成。关键参数有:
- 分频系数(Pre-divider / Post-divider)
- 倍频系数(Multiplier)
- 输出分频(Output Divider)
公式很简单:PLL 输出频率 = MCLK / Pre-divider × Multiplier / Post-divider
举个例子,某 Sensor 需要 720MHz 的内部时钟,MCLK 是 24MHz:
Pre-divider = 1
Multiplier = 60
Post-divider = 2
PLL 输出 = 24 / 1 × 60 / 2 = 720 MHz
注意:PLL 配置必须在 Sensor 进入“正常模式”之前完成。如果先让 Sensor 开始输出图像,再改 PLL 参数,会导致输出时钟抖动,图像出现条纹。
3.5 硬件初始化序列编写
好了,现在我们把所有步骤串起来。一个标准的硬件初始化序列,长这样:
- 上电: DVDD → AVDD → IOVDD(按 Datasheet 顺序)。每步间隔 1~5ms。
- 提供 MCLK: 主控输出时钟到 Sensor。
- 释放 Reset: 拉高 Reset 引脚。
- 等待: 延时 10ms,等待内部 PLL 锁定。
- I2C 初始化: 写入 Sensor 的初始化寄存器序列(包括 PLL 配置、输出格式、增益等)。
- 退出 Standby: 拉低 Standby 引脚(或写寄存器),让 Sensor 进入 streaming 模式。
- 等待: 等待几帧时间,直到图像稳定。
下面是一个简化的代码示例(伪代码):
// 1. 上电
power_on(DVDD, 1.2V);
delay_ms(2);
power_on(AVDD, 2.8V);
delay_ms(2);
power_on(IOVDD, 1.8V);
delay_ms(5);
// 2. 提供 MCLK
gpio_mclk_enable(24_MHz);
// 3. 释放 Reset
gpio_set(RESET_PIN, HIGH);
delay_ms(10);
// 4. I2C 初始化序列
sensor_write_reg(0x0103, 0x01); // 软件复位
delay_ms(5);
sensor_write_reg(0x0300, 0x01); // PLL pre-divider
sensor_write_reg(0x0301, 0x3C); // PLL multiplier (60)
sensor_write_reg(0x0302, 0x02); // PLL post-divider
// ... 其他寄存器配置
// 5. 退出 Standby,开始输出
sensor_write_reg(0x0100, 0x01); // 进入 streaming 模式
delay_ms(100); // 等待图像稳定
我的习惯:在 I2C 初始化序列的最后,读一个已知值的寄存器做校验。如果读回来的值不对,说明初始化失败,需要重新上电或报错。这个习惯帮我抓出过好几次硬件虚焊的问题。
3.6 知识结构图:Sensor 上电与初始化流程
下面这张图,把整个流程串起来了。你可以把它贴在工位上,每次调试时对照着看。
3.7 常见问题与避坑
- 图像全黑或全白: 先检查电源电压是否到位。用示波器量 DVDD、AVDD、IOVDD 的波形,看是否有跌落。
- I2C 写不进去: 检查 IOVDD 是否和主控的 I2C 电平匹配。1.8V 对 1.8V,2.8V 对 2.8V。电平不匹配,通信会失败。
- 图像闪烁: 大概率是 MCLK 不稳定,或者 PLL 配置有误。用频谱仪看时钟,确认频率和抖动。
- Sensor 发热严重: 检查是否进入了正确的模式。有些 Sensor 在待机模式下电流应该只有几 mA,如果达到几十 mA,说明没进入待机。
一句话总结:上电时序是 Sensor 的“生命线”。顺序错了,后面所有努力都是白费。每次拿到新 Sensor,第一件事就是画时序图,然后对着 Datasheet 逐条核对。