3. 卷帘快门工作原理:逐行曝光与读出时序

卷帘快门,说白了就是让传感器一行一行地干活。它不是所有像素同时曝光,而是像窗帘一样从上到下扫过去。我第一次接触这个概念时,也觉得挺反直觉的——为什么不能一起拍?

嗯,这背后有很现实的硬件原因。今天我们就把它彻底讲透。

3.1 逐行曝光与读出:卷帘快门的核心动作

卷帘快门的工作流程可以拆成三步:

  1. 复位行:把某一行像素的电荷清空,准备开始曝光。
  2. 等待曝光:该行像素开始积累光生电荷,时间由曝光时长决定。
  3. 读出行:曝光结束后,把这一行的电荷逐像素转换成电压,送到ADC。

这三步是流水线式进行的。当第N行在读出的同时,第N+1行可能正在曝光,第N+2行可能刚被复位。我习惯把这个过程想象成「三行并行流水线」。

关键点:卷帘快门没有全局的「曝光开始」和「曝光结束」信号。每一行的曝光起始时刻都不同,相差一个行周期。

为什么会这样?因为读出电路(列ADC或片内ADC)一次只能处理一行数据。如果所有行同时曝光结束,读出电路会瞬间被撑爆。所以硬件设计者选择了「错峰出行」。

3.2 帧周期与行周期:两个核心时间参数

搞卷帘快门时序,你绕不开两个参数:行周期(Row Time, T_row)和帧周期(Frame Time, T_frame)。

3.2.1 行周期 T_row

行周期是指处理完一行数据所需的总时间。它包括:

  • 像素复位时间:给行选通信号,复位该行像素的FD节点。
  • 信号建立时间:等待像素输出稳定。
  • ADC转换时间:把模拟信号转成数字码。
  • 数据读出时间:通过MIPI或LVDS接口把数据送出去。

我见过不少工程师只盯着ADC转换时间算行周期,结果流片回来发现读出接口带宽不够,帧率直接腰斩。所以我的建议是:行周期 = max(ADC转换时间, 数据读出时间) + 余量。

实战经验:我曾经在一个1080p@60fps的项目里,算出来行周期需要约18.5μs。但实际测试时发现,MIPI D-PHY的线速率只能跑到1.2Gbps/lane,数据读出时间反而成了瓶颈。最后不得不把行周期放宽到20μs,帧率降到55fps才稳定。

3.2.2 帧周期 T_frame

帧周期就是完整读完一帧图像所需的时间。对于卷帘快门,它等于:

T_frame = T_row × 有效行数 + 垂直消隐时间

垂直消隐时间(VBLANK)是帧与帧之间的间隔,用来做一些「家务活」:

  • 复位所有像素的电荷
  • 更新寄存器配置(比如增益、曝光时间)
  • 等待外部同步信号

我习惯把VBLANK留出至少10~20行的时间。太短了,寄存器更新可能来不及生效;太长了,浪费帧率。

参数 典型值(1080p@60fps) 说明
有效行数 1080 实际成像行数
行周期 T_row 18.5 μs 含ADC+读出
垂直消隐 VBLANK 20 行 约370 μs
帧周期 T_frame 20.35 ms 约49 fps

3.3 行间串扰:卷帘快门的「阿喀琉斯之踵」

行间串扰,说白了就是上一行的信号「污染」了下一行。这在卷帘快门里是个老大难问题。

3.3.1 串扰的三种来源

  1. 电荷共享:当一行正在读出时,相邻行的像素可能通过衬底或阱区发生电荷扩散。尤其是高光照场景下,过饱和像素的电荷会「溢」到隔壁行。
  2. 时钟耦合:行选通信号、复位信号的跳变会通过寄生电容耦合到相邻行的像素输出线上。我在一个项目里遇到过,行选通上升沿刚好落在ADC采样窗口内,导致整行出现固定竖条纹。
  3. 电源噪声:一行读出时的大电流冲击会拉低内部电源电压,影响正在曝光的其他行的偏置电压。

避坑指南:我曾经调试过一个低光照相机模组,发现暗场下每隔几行就有一条亮线。查了三天,最后发现是行选通信号的上升沿太陡(<1ns),通过像素内部的寄生电容耦合到了FD节点。解决办法是在行选通驱动器的输出端加一个RC滤波,把边沿斜率降到3~5ns。

3.3.2 如何量化行间串扰

行间串扰通常用「串扰比」来衡量:

串扰比 = (受影响行的输出变化量) / (干扰行的输出变化量)

比如,让第N行接受强光照射(输出接近满阱),然后测量第N+1行在暗场下的输出。如果第N+1行本应是暗电平,却读出了10个DN(数字码),而第N行的满阱输出是1000 DN,那么串扰比就是1%。

我一般要求串扰比控制在0.5%以下。超过1%的话,图像上就能肉眼看到行间纹理了。

3.4 卷帘快门时序的SVG图解

下面这张图展示了卷帘快门三行流水线的时序关系。我特意把复位、曝光、读出三个动作画在同一时间轴上,方便你理解「错峰」的含义。

卷帘快门逐行流水线时序 t0 t 复位 曝光 读出 第N行 复位 曝光 读出 第N+1行 复位 曝光 读出 第N+2行 行周期 T_row 帧周期 T_frame 流水线特点 • 三行同时工作 • 每行曝光时长相同 • 起始时刻相差T_row

从图上可以清楚看到:第N行曝光结束时,第N+1行才曝光到一半,第N+2行刚开始曝光。这就是卷帘快门「逐行」的本质。

3.5 实战中的时序计算

假设我们要设计一个500万像素(2592×1944)的传感器,目标帧率30fps。我们来算算行周期和消隐时间。

步骤1:确定帧周期

T_frame = 1 / 30 = 33.33 ms

步骤2:估算行周期

假设ADC转换时间 = 8 μs,数据读出时间 = 10 μs(4 lane MIPI,每lane 1.5 Gbps),那么:

T_row = max(8, 10) + 2 μs余量 = 12 μs

步骤3:计算有效读出时间

有效行数 = 1944,T_row × 1944 = 12 μs × 1944 = 23.33 ms

步骤4:计算垂直消隐

VBLANK = T_frame - 有效读出时间 = 33.33 - 23.33 = 10 ms

换算成行数:10 ms / 12 μs ≈ 833 行

我的习惯:VBLANK留出833行看起来很多,但实际项目中我会先留500行,然后根据寄存器更新时间、PLL锁定时间等实际需求再调整。留太多VBLANK会浪费帧率,留太少又可能出bug。

3.6 行间串扰的实测与调试

最后聊聊怎么在实验室里抓行间串扰。我常用的方法很简单:

  1. 拍一张均匀光照的灰卡,确保所有行输出一致。
  2. 在画面中间区域放一个强光点(比如LED手电筒),让某几行过饱和。
  3. 观察过饱和行上下几行的输出。如果出现亮线或暗线,说明有串扰。

串扰的波形在示波器上很容易辨认:读出过饱和行时,电源电压会有一个明显的跌落,然后恢复。这个跌落如果发生在相邻行的ADC采样窗口内,就会导致该行读出值偏小(暗线)。

避坑指南:我曾经遇到过一个案例,串扰只在特定增益下出现。查到最后发现是片内LDO的负载调整率不够,高增益下电源抑制比(PSRR)下降,行读出时的电流波动直接耦合到了像素参考电压上。解决办法是换了一颗PSRR更高的LDO,串扰从1.8%降到了0.3%。