摄像头配置——OV5640配置输出RAW格式

OV5640模组架构

该模组最大支持2592x1944尺寸的图像输出,这里注意以下信号即可

XVCLK:输出时钟,该时钟输入后可以通过PLL分频/倍频后提供给模组各个功能子模块。

PWDN:掉电使能信号,正常工作时应保持为低电平

PCLK:随像素同步输出的像素时钟

HREF:随像素同步输出的行数据有效信号(参考VGA时序介绍)

VSYNC:场同步信号

SIOC:SCCB信号时钟

SIOD:SCCB信号数据

D[9:0]:DVP数据 输出

MCP/N:MIPI时钟

MDP/N[1:0]:MIPI 数据输出

OV5640模组原理图

D[9:0](D9:MSB、D0:LSB)是传感器RGBRAW10位输出。D[9:2](D9:MSB、D2:LSB)为8位输出。

MCP/MCN:MIPI差分时钟输出

MDP0/MDN0:第一路数据

MDP1/MDN1:第二路数据

通过上述原理图,DVP和MIPI输出功能是共用一些引脚的,所以只能选择一种作为数据输出,输出类型可以通过SCCB总线配置摄像头寄存器(0x300e寄存器)来进行控制的。

SCCB总线实际上就是IIC的裁剪版本,可以参考接口协议学习(三):SCCB(与I2C比较)_sccb i2c-CSDN博客

ATK-MC5640 V1.2模块

该模块采用 OmniVision 公司的 OV5640 摄像头传感器作为核心,OV5640 是一颗 1/4 英寸 CMOS QSXGA (2592*1944)的图像传感器。

ATK-MC5640 模块的原理图如下:

ATK-MC5640 模块自带了有源晶振,用于产生 24MHz 的时钟作为 OV5640 传感器的 XCLK 输入,模块的闪光灯(LED1 LED2)可由 OV5640 STROBE 脚控制(可编程控制)或外部引脚控制。ATK-MC5640 模块通过一个 2*9 的排针(P1)同外部电路连接,各引脚的详细描述, 如下表所示:

正点原子给的模组输出数据部分只接了D[9:2],DVP输出RAW的时候会有精度损失。

摄像头配置

摄像头的通用配置总结大致包括以下:

输出尺寸配置、输出格式配置、时钟相关配置、使能配置、其他功能配置

输出尺寸配置

OV5640图像传感器的窗口描述如下图所示:

与图像传感器的窗口配置寄存器如上图,我们要配置成输出2592x1944,physical pixel size的尺寸为2624x1952,配置X_ADDR_ST和Y_ADDR_ST为都为0,X_OFFSET为16,Y_OFFSET为8,得到的pre-scaling size为2592x1944(2592=2624-16x2,1944=1952-8x2),data output size上设置成与pre-scaling size一样,当数据输出窗口的宽高比例与预缩放窗口的宽高比例不一致时,输出的图像数据会变形,只有当两者比例一致时,输出图像的尺寸才不会变形。

	///都配置为0表示开窗起始为X和Y都为0
	sccb_write_reg16(0x3800, 0x00);  //X_ADDR_ST高字节[11:8]
	sccb_write_reg16(0x3801, 0x00);  //X_ADDR_ST低字节
	sccb_write_reg16(0x3802, 0x00);  //Y_ADDR_ST高字节[10:8]
	sccb_write_reg16(0x3803, 0x00);  //Y_ADDR_ST低字节
	//X_ADDR_END和Y_ADDR_END
	sccb_write_reg16(0x3804, 0x0a);
	sccb_write_reg16(0x3805, 0x3f);  //0x0a3f=2623  ,0~2623
	sccb_write_reg16(0x3806, 0x07);
	sccb_write_reg16(0x3807, 0x9f);  //0x079f=1951  ,0~1951
	//配置输出尺寸为2592x1944
	sccb_write_reg16(0x3808, 0x0a);  //DVP 输出水平像素点数高4位
	sccb_write_reg16(0x3809, 0x20);  //DVP 输出水平像素点数低8位    0x0a20=2592
	sccb_write_reg16(0x380a, 0x07);  //DVP 输出垂直像素点数高3位
	sccb_write_reg16(0x380b, 0x98);  //DVP 输出垂直像素点数低8位    0x0798=1944

	sccb_write_reg16(0x380c, 0x0b);  //水平总像素大小高5位
	sccb_write_reg16(0x380d, 0x1c);  //水平总像素大小低8位         HTS 0x0b1c=2844
	sccb_write_reg16(0x380e, 0x07);  //垂直总像素大小高5位
	sccb_write_reg16(0x380f, 0xb0);  //垂直总像素大小低8位         VTS 0x07b0=1968
	sccb_write_reg16(0x3810, 0x00);
	sccb_write_reg16(0x3811, 0x10);  //X_OFFSET 0x0010=16 ,2624-16x2=2592
	sccb_write_reg16(0x3812, 0x00);
	sccb_write_reg16(0x3813, 0x04);  //Y_OFFSET 0x0004=4  ,1952-8x2 =1944   输出窗口的宽高比例与预缩放窗口宽高比例一致(1:1),不会变形
	

代码中需要注意的是HTS(H-Total)和VTS(V-Total)寄存器,也就是除了有效数据(HREF有效)外的一些空白地方。帧率FPS = PCLK / (VTS * HTS )

输出格式配置

OV5640支持多种输出格式,如RawRGB、RGB565RGB555RGB444CCIR656、YUV422YUV420、YCbCr422 和压缩图像(JPEG)输出格式。甚至RAW的格式(RGGB、GBRG、GRBG、BGGR)也可以通过formattter module进行设置。输出格式的主要使用的寄存器为FORMAT CONTROL00(0x4300)寄存器。该寄存器的bit[7:4]设置从formatter module输出的格式,bit[3:0]设置该格式下像素的顺序。

实际上,直接Bypass formatter module,然后直接输出RAW即可,因此该寄存器的配置如下:

sccb_write_reg16(0x4300, 0xf8);

时钟相关配置

时钟配置可参考:OV5640 PCLK计算方法_ov5640的pclk-CSDN博客

 OV5640内部PLL的时钟树如下所示,XVCLK为24MHz输入时钟,项目中PCLK需要配置成96MHz【96M/(2844x1968) = 17左右】,因此这样配置实际输出的RAW图像帧率是17 FPS

根据以上时钟树,96MHz时钟生成过程如下:

1、24M/3=8M       (0x3037[3:0]=3)

 2、8Mx120=960M    (0x3037[7]=0 && 0x3036[6:0]=120 )

3、960M/1=960M    (0x3035[7:4]=1)

4、960M/2=480M    (0x3037[4]=1)

5、480M/2.5=192M  (0x3034[3:0]=a)

6、192M/1=192M    (0x3108[5:4]=0)

7、192/(1x2)=96M  (0x3035[3:0]=1 && DVP)   即为PCLK

这里有个DIV_PCLK不知道干啥的


	sccb_write_reg16(0x3008, 0x42);   //取消软件复位
	sccb_write_reg16(0x3103, 0x03);   //时钟从PLL获取

	//分频参考:https://blog.csdn.net/wolfhunterhu/article/details/135264200
	// 24M/3=8M       (0x3037[3:0]=3)
	// 8Mx120=960M    (0x3037[7]=0 && 0x3036[6:0]=120 )
	// 960M/1=960M    (0x3035[7:4]=1)
	// 960M/2=480M    (0x3037[4]=1)
	// 480M/2.5=192M  (0x3034[3:0]=a)
	// 192M/1=192M    (0x3108[5:4]=0)
	// 192/(1x2)=96M  (0x3035[3:0]=1 && DVP)   即为PCLK
	sccb_write_reg16(0x3034, 0x1a);
	//系统时钟分频 Bit[7:4]:系统时钟分频 input clock =24Mhz, PCLK = 96Mhz
	sccb_write_reg16(0x3035,0x11);
//	sccb_write_reg16(0x3036,0x3c);  //PLL倍频  //48M
//	sccb_write_reg16(0x3036, 0x5A); //PLL倍频  //72M
	sccb_write_reg16(0x3036, 0x78); //PLL倍频  //96M即PCLK
	//后续试一试更高频率的下高速时钟
	sccb_write_reg16(0x3037, 0x13); //PLL分频控制
	sccb_write_reg16(0x3108, 0x01); //系统根分频器

使能配置

配置0x3017和0x3018寄存器,对应位置1使能时序信号和数据信号的输出

	sccb_write_reg16(0x3017, 0xff);
	sccb_write_reg16(0x3018, 0xff);

由于需要输出RAW原始图,因此对于OV5640内部对于图像操作的模块进行Disable以保证输出的RAW图是直接从图像传感器输出的且未经任何处理。

	sccb_write_reg16(0x5000, 0x00);  //ISP CONTROL00 ,不使能相关算法
	sccb_write_reg16(0x5001, 0x00);  //ISP CONTROL01 ,同样不使能算法

其他功能配置

其他配置如AEC曝光相关的寄存器配置、AGC模拟增益相关的配置,这与自动曝光算法相关,后续在讲解自动曝光算法时统一介绍。还有一些寄存器配置手册里没提到,先保持默认配置。

总的配置代码如下:


	sccb_write_reg16(0x3008, 0x42);   //取消软件复位
	sccb_write_reg16(0x3103, 0x03);   //时钟从PLL获取
	//使能FREX、VSYNC、HREF、PCLK、D[9:0]、GPIO0/GPIO1输出
	sccb_write_reg16(0x3017, 0xff);
	sccb_write_reg16(0x3018, 0xff);

	// 24M/3=8M       (0x3037[3:0]=3)
	// 8Mx120=960M    (0x3037[7]=0 && 0x3036[6:0]=120 )
	// 960M/1=960M    (0x3035[7:4]=1)
	// 960M/2=480M    (0x3037[4]=1)
	// 480M/2.5=192M  (0x3034[3:0]=a)
	// 192M/1=192M    (0x3108[5:4]=0)
	// 192/(1x2)=96M  (0x3035[3:0]=1 && DVP)   即为PCLK
	sccb_write_reg16(0x3034, 0x1a);
	//系统时钟分频 Bit[7:4]:系统时钟分频 input clock =24Mhz, PCLK = 96Mhz
	sccb_write_reg16(0x3035,0x11);
//	sccb_write_reg16(0x3036,0x3c);  //PLL倍频  //48M
//	sccb_write_reg16(0x3036, 0x5A); //PLL倍频  //72M
	sccb_write_reg16(0x3036, 0x78); //PLL倍频  //96M即PCLK
	//后续试一试更高频率的下高速时钟
	sccb_write_reg16(0x3037, 0x13); //PLL分频控制
	sccb_write_reg16(0x3108, 0x01); //系统根分频器


	sccb_write_reg16(0x3630, 0x36);
	sccb_write_reg16(0x3631, 0x0e);
	sccb_write_reg16(0x3632, 0xe2);
	sccb_write_reg16(0x3633, 0x12);
	sccb_write_reg16(0x3621, 0xe0);
	sccb_write_reg16(0x3704, 0xa0);
	sccb_write_reg16(0x3703, 0x5a);
	sccb_write_reg16(0x3715, 0x78);
	sccb_write_reg16(0x3717, 0x01);
	sccb_write_reg16(0x370b, 0x60);
	sccb_write_reg16(0x3705, 0x1a);
	sccb_write_reg16(0x3905, 0x02);
	sccb_write_reg16(0x3906, 0x10);
	sccb_write_reg16(0x3901, 0x0a);
	sccb_write_reg16(0x3731, 0x12);

	sccb_write_reg16(0x3600, 0x08);
	sccb_write_reg16(0x3601, 0x33);
	sccb_write_reg16(0x302d, 0x60);
	sccb_write_reg16(0x3620, 0x52);
	sccb_write_reg16(0x371b, 0x20);
	sccb_write_reg16(0x471c, 0x50);
	sccb_write_reg16(0x3a13, 0x43);  //AEC CTRL13 Bit[6]:pre-gain enable  Bit[5:0]:pre-gain=3
	sccb_write_reg16(0x3a18, 0x00);  //AEC GAIN CEILING[9:8]
	sccb_write_reg16(0x3a19, 0xf8);  //AEC GAIN CEILING[7:0]
	sccb_write_reg16(0x3635, 0x13);
	sccb_write_reg16(0x3636, 0x03);
	sccb_write_reg16(0x3634, 0x40);
	sccb_write_reg16(0x3622, 0x01);
	sccb_write_reg16(0x3c01, 0x34);  // (50/60HZ detect) 5060HZ CTRL01
	sccb_write_reg16(0x3c04, 0x28);  // 5060HZ CTRL04
	sccb_write_reg16(0x3c05, 0x98);  // 5060HZ CTRL05
	sccb_write_reg16(0x3c06, 0x00);  // LIGHT METER1 THRESHOLD[15:8]
	sccb_write_reg16(0x3c07, 0x08);  // LIGHT METER1 THRESHOLD[7:0]
	sccb_write_reg16(0x3c08, 0x00);  // LIGHT METER2 THRESHOLD[15:8]
	sccb_write_reg16(0x3c09, 0x1c);  // LIGHT METER2 THRESHOLD[7:0]
	sccb_write_reg16(0x3c0a, 0x9c);  // SAMPLE NUMBER[15:8]
	sccb_write_reg16(0x3c0b, 0x40);  // SAMPLE NUMBER[7:0]
	sccb_write_reg16(0x3820, 0x46);  // ISP vflip和Sensor vflip
	sccb_write_reg16(0x3821, 0x00);  // JPEG mirror H-binning相关


	///都配置为0表示开窗起始为X和Y都为0
	sccb_write_reg16(0x3800, 0x00);  //X_ADDR_ST高字节[11:8]
	sccb_write_reg16(0x3801, 0x00);  //X_ADDR_ST低字节
	sccb_write_reg16(0x3802, 0x00);  //Y_ADDR_ST高字节[10:8]
	sccb_write_reg16(0x3803, 0x00);  //Y_ADDR_ST低字节
	//X_ADDR_END和Y_ADDR_END
	sccb_write_reg16(0x3804, 0x0a);
	sccb_write_reg16(0x3805, 0x3f);  //0x0a3f=2623  ,0~2623
	sccb_write_reg16(0x3806, 0x07);
	sccb_write_reg16(0x3807, 0x9f);  //0x079f=1951  ,0~1951
	//配置输出尺寸为2592x1944
	sccb_write_reg16(0x3808, 0x0a);  //DVP 输出水平像素点数高4位
	sccb_write_reg16(0x3809, 0x20);  //DVP 输出水平像素点数低8位    0x0a20=2592
	sccb_write_reg16(0x380a, 0x07);  //DVP 输出垂直像素点数高3位
	sccb_write_reg16(0x380b, 0x98);  //DVP 输出垂直像素点数低8位    0x0798=1944

	sccb_write_reg16(0x380c, 0x0b);  //水平总像素大小高5位
	sccb_write_reg16(0x380d, 0x1c);  //水平总像素大小低8位         HTS 0x0b1c=2844
	sccb_write_reg16(0x380e, 0x07);  //垂直总像素大小高5位
	sccb_write_reg16(0x380f, 0xb0);  //垂直总像素大小低8位         VTS 0x07b0=1968
	sccb_write_reg16(0x3810, 0x00);
	sccb_write_reg16(0x3811, 0x10);  //X_OFFSET 0x0010=16 ,2624-16x2=2592
	sccb_write_reg16(0x3812, 0x00);
	sccb_write_reg16(0x3813, 0x04);  //Y_OFFSET 0x0004=4  ,1952-8x2 =1944   输出窗口的宽高比例与预缩放窗口宽高比例一致(1:1),不会变形
	sccb_write_reg16(0x3814, 0x11);
	sccb_write_reg16(0x3815, 0x11);

	sccb_write_reg16(0x3618, 0x00);
	sccb_write_reg16(0x3612, 0x29);
	sccb_write_reg16(0x3708, 0x64);
	sccb_write_reg16(0x3709, 0x52);
	sccb_write_reg16(0x370c, 0x03);
	sccb_write_reg16(0x3a02, 0x03);  //禁用了夜间模式
	sccb_write_reg16(0x3a03, 0xd8);
	sccb_write_reg16(0x3a08, 0x01);  //AEC B50 STEP[9:8]
	sccb_write_reg16(0x3a09, 0x27);  //AEC B50 STEP[7:0]
	sccb_write_reg16(0x3a0a, 0x00);  //AEC B60 STEP[9:8]
	sccb_write_reg16(0x3a0b, 0xf6);  //AEC B60 STEP[7:0]
	sccb_write_reg16(0x3a0e, 0x03);  //AEC CTRL0E
	sccb_write_reg16(0x3a0d, 0x04);  //AEC CTRL0D
	sccb_write_reg16(0x3a14, 0x03);  //AEC MAX EXPO(50Hz) [15:8]
	sccb_write_reg16(0x3a15, 0xd8);  //AEC MAX EXPO(50Hz) [7:0]
	sccb_write_reg16(0x4001, 0x02);  //BLC CTRL01(BLC start line)
	sccb_write_reg16(0x4004, 0x02);  //BLC CTRL04
	sccb_write_reg16(0x3000, 0x00);  //SYSTEM RESET00 复位相关模块
	sccb_write_reg16(0x3002, 0x1c);  //SYSTEM RESET02
	sccb_write_reg16(0x3004, 0xff);  //CLOCK ENABLE00
	sccb_write_reg16(0x3006, 0xc3);  //CLOCK ENABLE02
	sccb_write_reg16(0x300e, 0x58);  //MIPI CONTROL00    Bit[2]:mipi_en 在该处配置成了dvp模式
	sccb_write_reg16(0x302e, 0x00);
	sccb_write_reg16(0x4300, 0xf8);  //Format Control00 Raw
	sccb_write_reg16(0x501f, 0x03);  //FORMAT MUX CONTROL :ISP RAW(DPC)
	sccb_write_reg16(0x4713, 0x03);  //JPEG MODE SELECT
	sccb_write_reg16(0x4407, 0x04);  //JPEG CTRL07
	sccb_write_reg16(0x440e, 0x00);
	sccb_write_reg16(0x460b, 0x37);
	sccb_write_reg16(0x460c, 0x20);  // VIFIFO CTRL0C
	sccb_write_reg16(0x4837, 0x22);  // DVP CLK divider
	sccb_write_reg16(0x3824, 0x02);  // DVP CLK divider
	sccb_write_reg16(0x5000, 0x00);  //ISP CONTROL00 ,不使能相关算法
	sccb_write_reg16(0x5001, 0x00);  //ISP CONTROL01 ,同样不使能算法
	//AEC使用寄存器(0x3A0F)、(0x3A10)、(0x3A1B)和(0x3A1E)来控制图像亮度,目标亮度AVG(0x56A1)
	sccb_write_reg16(0x3a0f, 0x36);  //高阈值
	sccb_write_reg16(0x3a10, 0x2e);  //低阈值
	sccb_write_reg16(0x3a1b, 0x38);  //从稳定状态变为不稳定状态的高阈值  ,图像亮度平均值应该保持在这个范围内
	sccb_write_reg16(0x3a1e, 0x2c);  //从稳定状态变为不稳定状态的低阈值
	//寄存器(0x3A11)和寄存器(0x3A1F)在手动速度选择中控制快速AEC范围。如果目标图像AVG读出(0x56A1)大于(0x3A11),则AEC将减少一半。如果寄存器AVG读数(0x56A1)小于(0x3A1F),则AEC将翻倍。
	sccb_write_reg16(0x3a11, 0x70);
	sccb_write_reg16(0x3a1f, 0x18);
	sccb_write_reg16(0x3008, 0x02);  //software power down/software reset
	sccb_write_reg16(0x3400, 0x04);  //AWB R GAIN[11:8]
	sccb_write_reg16(0x3401, 0x00);  //AWB R GAIN[7:0]
	sccb_write_reg16(0x3402, 0x04);  //AWB G GAIN[11:8]
	sccb_write_reg16(0x3403, 0x00);  //AWB G GAIN[7:0]
	sccb_write_reg16(0x3404, 0x04);  //AWB B GAIN[11:8]
	sccb_write_reg16(0x3405, 0x00);  //AWB B GAIN[7:0]
	sccb_write_reg16(0x3406, 0x01);  //AWB MANUAL CONTROL :Manual
	sccb_write_reg16(0x4000, 0x88);  //BLC CTRL00  没使能
	sccb_write_reg16(0x3503, 0x03);  //AEC PK MANUAL :AEC/AGC manual enable

	unsigned int cmos_exposure = 0x300;
	unsigned int cmos_gain = 0xa0;
	//AEC manual
    sccb_write_reg16(0x3500, 0x00);// Exposure [19:16]
	sccb_write_reg16(0x3501, (cmos_exposure>>4)&0x3f);// Exposure [15:8]
	sccb_write_reg16(0x3502, (cmos_exposure&0x0f)<<4);// Exposure [7:0]
	//AGC manual
	sccb_write_reg16(0x350a, (cmos_gain>>8)&0x3);     // Real gain[9:8]
	sccb_write_reg16(0x350b, cmos_gain&0x0ff);        // Real gain[7:0]

参考

MIPI接口协议及规范理解 - 知乎

 硬件接口之MIPI_mipi接口定义-CSDN博客

blog.csdn.net/baidu_38797690/article/details/125292046

Camera | 2.MIPI、CSI基础 - 知乎

720P MIPI配置:OV5640_MIPI_1LEN调试记录_ov5640 mipi-CSDN博客

Camera开发-OV5640(MIPI)-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值