4. Sensor驱动基础:上电时序、初始化序列、寄存器配置,一个都不能错。
做Camera驱动这些年,我踩过最大的坑,就是Sensor上电时序。说句实话,很多刚入行的朋友觉得驱动开发就是调调I2C、改改寄存器。但真正到了项目里,你会发现——时序错了,后面全是白忙活。
今天这一章,我就把Sensor驱动最核心的三个环节掰开揉碎了讲。上电时序、初始化序列、寄存器配置,这三样东西,一个都不能错。
4.1 上电时序:Sensor的“生命开关”
Sensor上电,不是简单地把电接上就完事。它有一套严格的顺序要求。我习惯把它比作“启动一台精密仪器”——先给谁供电、后给谁供电、间隔多久,都有讲究。
典型的Sensor供电有三路:
- AVDD(模拟电压):通常2.8V,给像素阵列和模拟电路用
- DVDD(数字电压):通常1.2V或1.8V,给数字逻辑核心供电
- IOVDD(IO电压):通常1.8V,给I2C、MIPI等接口供电
上电顺序一般是:AVDD → DVDD → IOVDD。但不同厂商、不同型号的Sensor,顺序可能不一样。你想想看,如果先给IOVDD供电,但AVDD还没起来,内部模拟电路处于不确定状态,I2C通信就可能出问题。
除了供电顺序,复位信号也很关键。Sensor通常有一个XSHUT或RESET引脚。上电完成后,需要拉低再拉高,完成硬件复位。这个复位脉冲的宽度,Datasheet里会写——比如至少1ms。
我个人的习惯是:上电完成后,先等10ms,再拉高复位。为什么多等一会儿?因为电源稳定需要时间,尤其是大电容滤波的电路。别省这几毫秒,省了可能就出问题。
4.2 初始化序列:一步一步来,别跳步
上电完成,Sensor开始工作。但这时候它还是“出厂状态”,需要你通过I2C写入一系列寄存器,把它配置成你想要的模式。
初始化序列一般包括:
- 软件复位:让Sensor内部状态机回到初始态
- PLL配置:设置时钟频率,决定帧率
- 分辨率设置:输出尺寸、窗口裁剪
- 增益与曝光:模拟增益、数字增益、曝光时间
- 输出格式:RAW10、RAW12、YUV等
- MIPI配置:Lane数、速率、数据格式
- 启动输出:开启MIPI或DVP输出
这里有个容易犯的错:顺序搞反了。比如先配了输出格式,再配PLL。Sensor内部状态机可能不认,直接罢工。我建议你严格按照Datasheet里的初始化流程图来,别自己“优化”顺序。
来看一段典型的初始化代码(伪代码):
// 1. 软件复位
sensor_write(0x0103, 0x01); // 软件复位寄存器
delay_ms(10); // 等待复位完成
// 2. 配置PLL
sensor_write(0x0301, 0x0A); // PLL倍频系数
sensor_write(0x0303, 0x01); // PLL分频系数
delay_ms(5); // 等待PLL锁定
// 3. 设置分辨率
sensor_write(0x3801, 0x00); // X起始高字节
sensor_write(0x3802, 0x00); // X起始低字节
// ... 更多配置
// 4. 启动输出
sensor_write(0x0100, 0x01); // 开启Streaming
delay_ms(10); // 等待输出稳定
你看,每一步之间我都加了延时。这不是多余的,是血的教训换来的。
4.3 寄存器配置:读懂Datasheet,别靠猜
寄存器配置是Sensor驱动的核心。说白了,就是通过I2C往Sensor内部写值,告诉它“你要怎么干活”。
但寄存器配置最怕什么?照着Datasheet抄都抄错。我见过太多人,把地址写反了、把位域搞混了、把默认值当成配置值用了。
寄存器配置的几个要点:
- 地址要确认:8位还是16位?有些Sensor用8位地址,有些用16位。写错了,Sensor根本不响应。
- 位域要理解:一个寄存器8位,可能控制多个功能。比如bit[7:4]控制增益,bit[3:0]控制曝光。你写0xFF,可能把不该改的也改了。
- 只写需要的位:最好先读回当前值,修改对应位,再写回去。这叫“读-改-写”。
举个例子,配置Sensor的增益:
// 错误写法:直接写0x10,可能覆盖其他位
sensor_write(0x3500, 0x10);
// 正确写法:先读后改
uint8_t val = sensor_read(0x3500);
val = (val & 0xF0) | 0x01; // 只改低4位
sensor_write(0x3500, val);
你看,多了一行读操作,但安全多了。
4.4 避坑指南:我踩过的那些坑
做Sensor驱动这些年,我踩过的坑能写一本书。这里挑几个典型的说说:
- 上电时序反了:有一次我把DVDD和IOVDD的顺序搞反了,Sensor能工作,但图像有噪点。查了整整两天,最后发现是供电顺序导致内部LDO工作异常。
- 初始化序列少了延时:PLL配置后没等锁定,直接配分辨率。结果Sensor输出帧率只有标称的一半。加了5ms延时,问题解决。
- 寄存器地址搞错:某款Sensor的Datasheet里,寄存器地址是16位的,但我按8位写了。I2C通信一直报NACK,我还以为是硬件问题。
4.5 总结:三个“必须”
最后,我总结三个“必须”,你记好了:
- 上电时序必须严格遵循Datasheet:顺序、延时、电压值,一个都不能错。
- 初始化序列必须按部就班:别跳步,别省延时,每一步都要确认Sensor准备好了。
- 寄存器配置必须读-改-写:别直接写死值,先读回来,改对应位,再写回去。
Sensor驱动说难不难,说简单也不简单。但只要你把这三个环节做好了,后面调图像质量、优化延迟,才有基础。否则,你连图像都出不来,还谈什么性能调优?
下一章,我会讲MIPI接口的调试与常见问题。嗯,那个坑更多,到时候再聊。