012、Sensor 工作模式切换:Full Size、Binning、Skipping、Crop 模式的寄存器配置

012、Sensor 工作模式切换:Full Size、Binning、Skipping、Crop 模式的寄存器配置 012、Sensor 工作模式切换Full Size、Binning、Skipping、Crop 模式的寄存器配置一、从一次“黑屏”调试说起去年做一款50M主摄项目客户要求预览时用12.5M四合一Binning拍照切回50M Full Size。逻辑上很简单预览切Binning省带宽拍照切Full Size保细节。结果一跑预览正常一按快门——黑屏。ISP报“frame length mismatch”Sensor输出尺寸和预期对不上。查了两天最后发现是Binning切回Full Size时忘了把horizontal/vertical binning factor寄存器复位。Sensor内部还在做2x2合并但输出尺寸寄存器已经改成了50M的宽高导致每帧数据量不对ISP直接罢工。这个坑让我意识到Sensor模式切换不是简单的“改几个寄存器值”而是一套完整的时序、带宽、增益、黑电平校准的联动操作。今天就把这块硬骨头啃透。二、四种模式的核心差异先明确概念别被厂商文档绕晕。Full SizeSensor所有像素全部读出分辨率最大帧率最低。比如IMX586的48M全尺寸10bit下通常只有15fps左右。Binning相邻像素合并读出常见2x2或3x3。好处是信噪比提升相当于像素面积变大输出分辨率降低帧率可以翻倍。注意Binning分模拟合并和数字合并前者在读出前完成噪声更低后者在ADC之后做灵活性高但噪声略大。Skipping跳行跳列读出不合并。比如每2行取1行、每2列取1列分辨率降为1/4。缺点是容易产生摩尔纹和锯齿因为空间采样不均匀。现在主流Sensor基本用Binning替代Skipping但低端Sensor或特殊场景如高速连拍还会见到。Crop只读出感光区域的一部分相当于数字变焦的硬件基础。比如从全尺寸中心截取1920x1080区域。Crop不改变像素合并方式只改变读出窗口起始位置和大小。三、寄存器配置的“骨架”不同厂商Sony、Samsung、OmniVision寄存器地址不同但逻辑框架一致。以Sony IMX系列为例核心寄存器组包括// 模式选择寄存器0x0100 // 0x00 软件待机0x01 流模式 // 注意改模式前必须先进入待机否则寄存器写入无效 reg_write(0x0100, 0x00); // 先停流这里踩过坑不停直接写会卡死 // 输出尺寸寄存器 reg_write(0x0340, height); // 垂直总行数含消隐 reg_write(0x0341, height 8); reg_write(0x0342, width); // 水平总像素含消隐 reg_write(0x0343, width 8); // 有效输出尺寸 reg_write(0x0344, x_start); // 水平起始 reg_write(0x0345, x_start 8); reg_write(0x0346, y_start); // 垂直起始 reg_write(0x0347, y_start 8); reg_write(0x0348, x_end); // 水平结束 reg_write(0x0349, x_end 8); reg_write(0x034A, y_end); // 垂直结束 reg_write(0x034B, y_end 8); // Binning/Skipping控制0x0380 ~ 0x0387 reg_write(0x0380, bin_h_factor); // 水平binning系数0x11表示2x2 reg_write(0x0381, bin_h_factor 8); reg_write(0x0382, bin_v_factor); // 垂直binning系数 reg_write(0x0383, bin_v_factor 8); reg_write(0x0384, skip_h_factor); // 水平skip系数0x11表示2x2 reg_write(0x0385, skip_h_factor 8); reg_write(0x0386, skip_v_factor); reg_write(0x0387, skip_v_factor 8);关键点Binning和Skipping不能同时使能但有些Sensor允许混合模式比如水平Binning垂直Skipping看具体型号手册。四、Binning模式配置实战以2x2 Binning为例输出分辨率减半但帧率翻倍。配置时要注意Binning系数通常0x11表示2x20x12表示3x3但3x3不常见因为奇数合并会导致像素中心偏移输出尺寸必须和Binning后的分辨率匹配。比如全尺寸4000x30002x2 Binning后输出2000x1500但有些Sensor要求输出尺寸写全尺寸内部自动处理——别自己算错增益补偿Binning后信号强度翻倍4个像素合并成1个模拟增益需要相应降低否则过曝// 配置2x2 Binning模式IMX586示例 // 先进入待机 reg_write(0x0100, 0x00); mdelay(10); // 别这样写直接写0x01Sensor没准备好就崩 // 设置binning系数 reg_write(0x0380, 0x11); // 水平2x2 reg_write(0x0382, 0x11); // 垂直2x2 // 设置输出尺寸Binning后 reg_write(0x0340, 1500); // 垂直有效行 reg_write(0x0342, 2000); // 水平有效像素 // 调整增益经验值降低6dB reg_write(0x0204, 0x00); // 模拟增益寄存器高位 reg_write(0x0205, 0x80); // 1x增益原2x2 Binning前是2x这里踩过坑 // 切回流模式 reg_write(0x0100, 0x01);这里有个隐藏问题Binning后黑电平OB会变化。因为合并像素的暗电流叠加OB值需要重新校准。有些Sensor会自动调整但多数需要手动写OB寄存器。我遇到过切Binning后画面偏绿就是OB没更新导致的。五、Skipping模式配置陷阱Skipping现在用得少但做高速场景如720p 240fps时还会碰到。配置和Binning类似但寄存器不同// 2x2 Skipping配置 reg_write(0x0384, 0x11); // 水平skip 2x reg_write(0x0386, 0x11); // 垂直skip 2x // 注意Skipping时binning系数必须设为0x111x1即不合并 reg_write(0x0380, 0x11); reg_write(0x0382, 0x11);Skipping最大的坑是相位对齐。因为跳行跳列像素的Bayer模式会被破坏。比如RGGB排列跳一行后变成GBRGISP的demosaic算法会出错。解决方案是要么Sensor内部做Bayer重排高端Sensor支持要么ISP端根据Skipping模式重新映射Bayer顺序。别这样写直接当全尺寸Bayer处理画面会出彩色条纹。六、Crop模式窗口裁剪的细节Crop常用于数字变焦或画中画。配置相对简单但要注意边界对齐// 从全尺寸中心裁剪1920x1080 // 全尺寸4000x3000中心起始坐标 x_start (4000 - 1920) / 2; // 1040 y_start (3000 - 1080) / 2; // 960 x_end x_start 1920 - 1; // 2959 y_end y_start 1080 - 1; // 2039 reg_write(0x0344, x_start); reg_write(0x0346, y_start); reg_write(0x0348, x_end); reg_write(0x034A, y_end);Crop模式下输出尺寸寄存器0x0340/0x0342必须和裁剪后的尺寸一致否则ISP会报错。另外Crop区域的起始坐标必须是偶数Bayer排列要求奇数坐标会导致颜色错乱。这里踩过坑客户要求精确裁剪到1921x1081我说不行必须偶数对齐最后妥协成1920x1080。七、模式切换的时序控制这是最容易被忽略的部分。Sensor从一种模式切到另一种不是瞬间完成的。典型流程停流写0x01000x00等待VSYNC信号停止至少等2帧时间写寄存器所有模式相关寄存器一次性写入不要分多次写有些Sensor支持组写入用0x0104寄存器控制等待稳定切回流模式后等待至少1帧的消隐期再开始取图重新校准Binning/Crop切换后黑电平、增益、白平衡参数可能失效需要重新做3A// 模式切换完整流程伪代码 void switch_mode(int mode) { // 1. 停流 reg_write(0x0100, 0x00); wait_for_vsync(2); // 等2帧确保Sensor完全停止 // 2. 写模式寄存器 if (mode FULL_SIZE) { set_full_size_regs(); } else if (mode BINNING_2X2) { set_binning_2x2_regs(); } // 3. 切回流 reg_write(0x0100, 0x01); wait_for_vsync(1); // 等1帧让输出稳定 // 4. 重新校准重要 isp_black_level_calibrate(); isp_awb_reset(); }有些Sensor支持“无缝切换”即不停止流直接改寄存器但仅限于同分辨率下的增益、曝光调整。模式切换分辨率变化必须停流这是铁律。八、实战经验总结寄存器写入顺序先改尺寸相关再改Binning/Skipping最后改增益。别倒着写否则Sensor内部状态机可能乱掉消隐时间调整Binning后帧率翻倍但MIPI带宽可能不够。需要适当增加HBLANK水平消隐来降低带宽否则丢帧。公式MIPI速率 (width HBLANK) * (height VBLANK) * fps * bits_per_pixel。别算错单位Binning模式下的HDR如果Sensor支持HDR如DOL模式Binning会破坏HDR的时序。有些Sensor在Binning下自动禁用HDR有些不会——必须手动关调试工具用示波器抓MIPI的HSYNC和VSYNC看帧间隔是否稳定。如果切模式后帧率跳变大概率是消隐时间没配好文档陷阱厂商寄存器手册经常写“reserved”位别乱写。但有些“reserved”其实是内部状态位读出来可以判断模式是否切换成功。比如IMX586的0x0005寄存器bit[3]表示Binning是否生效最后说一句模式切换的稳定性取决于你停流后等了多久。别为了省那几毫秒把整个系统搞崩。我见过最离谱的案例切模式后等了0.5ms就取图结果前两帧全是花屏——因为Sensor内部PLL还没锁定。老老实实等2帧不丢人。