OV2640摄像头模块


目录

1:OV2640简介

2:OV2640输出时序

3:OV2640窗口设置

4:代码实现


1:OV2640简介

OV2640是OmniVision公司生产的一颗1/4寸的CMOS UXGA(1632*1232)图像传感器。

通过SCCB总线控制,可以输出整振,子采样,缩放和取窗口等方式的各种分辨率8/10位影像数据

UXGA最高15帧/秒 SVGA可达30帧 GIF可达60帧

UXGA:分辨率为1600*1200的输出格式,SXGA(1280*1024)、XVGA(1280*960)、WXGA(1280*800)、XGA(1024*768)、SVGA(800*600)、VGA(640*480)、CIF(352*288)和QQVGA(160*120)等。

特点:

  1. 支持UXGA,SXGA,SVGA以及从SXGA按比例缩小到40*30的任何尺寸
  2. 高灵敏度、低电压适合嵌入式应用
  3. 标准的SCCB接口,兼容IIC接口
  4. 支持RawRGB、RGB(RGB565/RGB555)、GRB422、YUV(422/420)和YCbCr(422)输出格式
  5. 支持自动曝光控制、自动增益控制、自动白平衡、自动消除灯光条纹、自动黑电平校准等自动控制功能。同时支持色饱和度、色相、伽马、锐度等设置。
  6. 支持图像缩放和闪光灯
  7. 支持图像压缩,即可输出JPEG图像数据

2:OV2640输出时序

先明白

  • PCLK:即像素时钟,一个PCLK时钟,输出一个(或半个)像素。
  • VSYNC:即帧同步信号。
  • HREF/HSYNC:即行同步信号。
  • Y[9:0]:一般只用8位数据,它是OV2640的图像数据输出,就是在PCLK,VSYNC和HREF/ HSYNC的控制下进行的

OV2640行输出时序

图像数据在HREF为高的时候输出,当HREF变高后,每一个PCLK时钟,输出一个字节数据。比如我们采用UXGA(1600*1200)时序,RGB565格式输出,每2个字节组成一个像素的颜色(低字节在前,高字节在后),这样每行输出总共有1600*2个PCLK周期,输出1600*2个字节

OV2640帧输出时序(UXGA)

OV2640支持:RGB565或JPEG输出。RGB565输出时,时序如图所示。JPEG输出时,PCLK大大减少,且HREF不连续,数据流以0XFF,0XD8开头,以0XFF,0XD9结束,将此间数据保存为.jpg即可在电脑打开查看。

3:OV2640窗口设置

OV2640最终输出的图像窗口大小取决于上图相关的设置

传感器窗口设置: 传感器窗口设置允许用户设置整个传感器区域(1632*1220)的感兴趣部分,也就是在传感器里面开窗,开窗范围从2*2~1632*1220都可以设置,不过要求这个窗口必须大于等于随后设置的图像尺寸。传感器窗口设置,通过0X03/0X19/0X1A/0X07/0X17/0X18等寄存器设置。

图像尺寸设置:也就是DSP输出(最终输出到LCD的)图像的最大尺寸,该尺寸要小于等于前面我们传感器窗口设置所设定的窗口尺寸。图像尺寸通过:0XC0/0XC1/0X8C等寄存器设置。

图像窗口设置:其实和前面的传感器窗口设置类似,只是这个窗口是在我们前面设置的图像尺寸里面,再一次设置窗口大小,该窗口必须小于等于前面设置的图像尺寸。该窗口设置后的图像范围,将用于输出到外部。图像窗口设置通过:0X51/0X52/0X53/0X54/0X55/0X57等寄存器设置。

图像输出大小设置:控制最终输出到外部的图像尺寸。该设置将图像窗口设置所决定的窗口大小,通过内部DSP处理,缩放成我们输出到外部的图像大小。该设置将会对图像进行缩放处理,如果设置的图像输出大小不等于图像窗口设置图像大小,那么图像就会被缩放处理,只有这两者设置一样大的时候,输出比例才是1:1的。图像输出大小通过:0X5A/0X5B/0X5C等寄存器设置。

4:代码实现

初始化过程:

  1. 初始化IO口
  2. 上电,并复位
  3. 读取传感器ID
  4. 执行初始化序列
  5. 完成初始化

前面说了,OV2640是通过SCCB来控制,来去对寄存器进行操作,这个SCCB就是理解为I2C的通信,也就两根线,也有起始信号,终止信号,应答信号。用这个模块的话,这个地方要注意一下,根据接线不同要修改初始化的IO口,至于读取传感器的ID,也就是通过SCCB去读取相应的寄存器,这个不用深究,代码基本上就是固定,

最后一步,执行初始化序列

1
2
3
4
    for(i=0;i<sizeof(ov2640_sxga_init_reg_tbl)/2;i++)
    {
        SCCB_WR_Reg(ov2640_sxga_init_reg_tbl[i][0],ov2640_sxga_init_reg_tbl[i][1]);
    }

这个就是在二维数组中把要设置的寄存器地址和要设置的内容打包,再通过SCCB将相应的内容写入到相应的寄存器里面,至于这个里面是个啥内容,不用深究,厂家给的,你自己写得把自己写疯,太多。

读取的过程,因为STM32中有DCMI打辅助,所有我们实际用摄像头起来会方便很多,DCMI帮助读取到数据后,还需要DMA的搬运,设置好DMA的运输的目的地址,存储器位宽等等参数,比如目的地址为屏幕,SRAM...,然后使能DMA传输,就可以读取OV2640模块图像的数据了。

注:有一点,很容易忽略,有的摄像头模块是自带时钟的,有的则没有,没有的需要用到软件配置提供时钟。

比如下面这个用内部高速时钟映射到PA8上来给摄像头提供时钟

1
2
3
4
5
6
7
8
9
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_MCO);
  /* Configure MCO (PA8) */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;  
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    RCC_MCO1Config(RCC_MCO1Source_HSI, RCC_MCO1Div_1);