3. Sensor驱动初始化:上电时序、PLL配置、输出格式设置、帧率控制
驱动Sensor,说白了就是让它从“死”到“活”的过程。很多人觉得初始化就是写几个寄存器,其实不然。我见过不少项目,Sensor能出图,但图像有各种奇怪的问题——比如闪屏、条纹、帧率不对——追根溯源,都是初始化阶段埋下的坑。
这一节,我们就把Sensor初始化的四个核心环节拆开揉碎。你跟着走一遍,以后拿到任何Sensor的datasheet,心里都有底。
3.1 上电时序:Sensor的“生命开关”
Sensor不是一通电就能工作的。它需要按照严格的顺序,依次施加不同的电压,并且每个电压之间还有时间间隔要求。这个顺序和间隔,就是上电时序。
为什么这么讲究?因为Sensor内部有多个电压域:模拟电路、数字核心、I/O接口。如果先给数字核心上电,模拟部分还没准备好,内部逻辑可能进入不确定状态。嗯,这就像电脑开机,你得先让电源稳定,再按启动键。
典型的CMOS Sensor上电时序包含以下步骤:
- 先上模拟电源(AVDD):通常为2.8V或3.3V,给像素阵列和模拟信号链供电。
- 再上数字核心电源(DVDD):通常为1.2V或1.8V,给逻辑电路供电。
- 最后上I/O电源(IOVDD):通常为1.8V或3.3V,给通信接口供电。
- 等待电源稳定:每个电源之间至少间隔1ms(具体看手册)。
- 拉高复位引脚:释放复位,Sensor开始内部初始化。
- 等待初始化完成:通常需要几毫秒到几十毫秒。
我建议你在驱动代码里,把每一步都加上明确的延时。别指望硬件自动搞定,软件做一次确认更保险。
3.2 PLL配置:给Sensor一个“心跳”
Sensor内部的所有操作——像素读出、ADC转换、数据输出——都需要一个时钟。这个时钟通常由内部的PLL(锁相环)产生。PLL的配置直接决定了Sensor的工作频率和帧率。
PLL配置的核心公式很简单:
输出频率 = 输入晶振频率 × (M / N) / P
其中:
- N:预分频系数,用于降低输入频率。
- M:倍频系数,用于提高频率。
- P:后分频系数,用于调整最终输出。
举个例子。假设输入晶振是24MHz,你想让Sensor内部工作频率为72MHz:
72MHz = 24MHz × (72 / 12) / 2
即:N=12, M=72, P=2
但要注意,PLL的M和N不是随便填的。每个Sensor都有频率范围限制:
| 参数 | 典型范围 | 说明 |
|---|---|---|
| 输入频率 | 6 ~ 27 MHz | 晶振或外部时钟 |
| VCO频率 | 100 ~ 800 MHz | PLL内部振荡器范围 |
| M/N比值 | 1 ~ 64 | 不同Sensor差异很大 |
| 输出频率 | 10 ~ 200 MHz | 取决于Sensor工艺 |
3.3 输出格式设置:让数据“说人话”
Sensor采集到的原始数据是Bayer格式的。但输出给ISP或主控时,可以选择不同的格式和位深。常见的输出格式有:
- RAW8/RAW10/RAW12:原始Bayer数据,位深不同。RAW12质量最好,但带宽要求高。
- YUV422:经过内部ISP处理后的彩色数据,适合直接显示。
- JPEG:压缩后的图像数据,适合存储和传输。
对于工业相机,我几乎只用RAW格式。为什么?因为原始数据保留了最多的信息,后续的色彩校正、去噪、锐化都可以在ISP里精细控制。用YUV或JPEG,相当于把处理权交给了Sensor内部的黑盒,你很难调出高质量的色彩。
输出格式的设置通常涉及以下几个寄存器:
- 输出位深选择:设置每个像素的bit数。
- 输出数据顺序:比如Bayer排列是RGGB还是BGGR。
- 输出接口模式:MIPI的lane数、CSI-2的数据类型。
- 数据对齐方式:高位对齐还是低位对齐。
// 示例:设置Sensor输出RAW10,Bayer顺序为RGGB
write_sensor_reg(0x3000, 0x0A); // 输出位深:RAW10
write_sensor_reg(0x3001, 0x00); // Bayer顺序:RGGB
write_sensor_reg(0x3002, 0x01); // MIPI 4-lane模式
write_sensor_reg(0x3003, 0x00); // 数据高位对齐
3.4 帧率控制:算清楚每一行的时间
帧率控制,说白了就是控制Sensor读出每一帧的速度。帧率的计算公式是:
帧率 = 1 / (VTS × 行时间)
其中:
- VTS:垂直总行数(包括有效行和消隐行)。
- 行时间:读取一行数据所需的时间。
而行时间又由水平总像素数和像素时钟决定:
行时间 = HTS / 像素时钟
其中HTS是水平总像素数(包括有效像素和消隐像素)。
所以,控制帧率有两种方法:
- 调整VTS:增加垂直消隐行数,帧率降低;减少则帧率升高。
- 调整像素时钟:通过PLL配置改变时钟频率。
我建议优先调整VTS。为什么?因为改变像素时钟会影响ADC的采样时间,可能引入噪点。而调整VTS只是改变了帧之间的空闲时间,对图像质量没有影响。
下面这张图展示了帧率控制的核心逻辑:
3.5 初始化流程总结
把上面四个环节串起来,一个完整的Sensor初始化流程应该是这样的:
- 上电:按AVDD → DVDD → IOVDD顺序供电,每步延时1ms以上。
- 复位:拉高复位引脚,等待Sensor内部初始化完成(通常10ms)。
- 读取ID:验证通信正常,确认Sensor型号正确。
- 配置PLL:根据目标帧率和输出格式,计算M/N/P值并写入寄存器。
- 配置输出格式:设置位深、Bayer顺序、MIPI参数。
- 配置帧率:调整VTS和HTS,确保帧率符合要求。
- 启动输出:使能Sensor的视频输出。