《ATK 您所在的位置:网站首页 xga时序 《ATK

《ATK

2023-04-01 03:05| 来源: 网络整理| 查看: 265

1)实验平台:正点原子 ATK-DFPGL22G开发板

2) 章节摘自【正点原子】ATK-DFPGL22G之FPGA开发指南_V1.0

3)购买链接:https://detail.tmall.com/item_o.htm?id=692712955836

4)全套实验源码+手册+视频下载地址:紫光PGL22G开发板 - 正点原子资料下载中心 1.0.0 文档

5)正点原子官方B站:正点原子官方的个人空间-正点原子官方个人主页-哔哩哔哩视频

6)FPGA技术交流QQ群:994244016

第四十一章 OV5640摄像头RGB-LCD显示实验

OV5640同OV7725一样,都是OmniVision(豪威科技)公司生产的CMOS图像传感器。不同的是,OV5640支持更高的分辨率、采集速率,具有更高的图像处理性能,主要应用在手机、数码相机、电脑多媒体等领域。本章将使用FPGA开发板实现对OV5640的数字图像采集并通过LCD实时显示。

本章分为以下几个章节:

41.1 简介

41.2 实验任务

41.3 硬件设计

41.4 程序设计

41.5 下载验证

41.1 简介

OV5640是一款1/4英寸单芯片图像传感器,其感光阵列达到2592*1944(即500W像素),能实现最快15fps QSXVGA(2592*1944)或者90fps VGA(640*480)分辨率的图像采集。传感器采用OmniVision推出的OmniBSI(背面照度)技术,使传感器达到更高的性能,如高灵敏度、低串扰和低噪声。传感器内部集成了图像处理的功能,包括自动曝光控制(AEC)、自动白平衡(AWB)等。同时该传感器支持LED补光、MIPI(移动产业处理器接口)输出接口和DVP(数字视频并行)输出接口选择、ISP(图像信号处理)以及AFC(自动聚焦控制)等功能。

OV5640的功能框图如下图所示:

图 41.1.1 OV5640功能框图

由上图可知,时序发生器(timing generator)控制着感光阵列(image array)、放大器(AMP)、AD转换以及输出外部时序信号(VSYNC、HREF和PCLK),外部时钟XVCLK经过PLL锁相环后输出的时钟作为系统的控制时钟;感光阵列将光信号转化成模拟信号,经过增益放大器之后进入10位AD转换器;AD转换器将模拟信号转化成数字信号,并且经过ISP进行相关图像处理,最终输出所配置格式的10位视频数据流。增益放大器控制以及ISP等都可以通过寄存器(registers)来配置,配置寄存器的接口就是SCCB接口,该接口协议兼容IIC协议。

OV5640使用的是两线式SCCB接口总线,有关SCCB总线的详细介绍可以参考“OV7725摄像头RGB-LCD显示实验”中的简介部分。虽然OV5640和OV7725都是采用SCCB接口总线来配置寄存器,但不同的是,OV7725是用8位(1个字节)来表示寄存器地址,而OV5640是用16位(两个字节)表示寄存器地址。

OV5640 SCCB的写传输协议如下图所示:

图 41.1.2 SCCB写传输协议

上图中的ID ADDRESS是由7位器件地址和1位读写控制位构成(0:写 1:读),OV5640的器件地址为7’h3c,所以在写传输协议中,ID Address(W)= 8’h78(器件地址左移1位,低位补0);Sub-address(H)为高8位寄存器地址,Sub-address(L)为低8位寄存器地址,在OV5640众多寄存器中,有些寄存器是可改写的,有些是只读的,只有可改写的寄存器才能正确写入;Write Data为8位写数据,每一个寄存器地址对应8位的配置数据。

在OV5640正常工作之前,必须先对传感器进行初始化,即通过配置寄存器使其工作在预期的工作模式,以及得到较好画质的图像。因为SCCB的写传输协议和IIC几乎相同,因此我们可以直接使用IIC的驱动程序来配置摄像头。当然这么多寄存器也并非都需要配置,很多寄存器可以采用默认的值。OV公司提供了OV5640的软件应用手册(位于开发板所随附的资料“7_硬件资料/4_OV5640资料/ OV5640摄像头模块软件使用手册_1.3_Sonix.pdf”),如果某些寄存器不知道如何配置可以参考此手册,下表是本程序用到的关键寄存器的配置说明。

表 41.1.1 OV5640关键寄存器配置说明

OV5640的寄存器较多,对于其它寄存器的描述可以参考OV5640的数据手册(位于开发板所随附的资料“7_硬件资料/4_OV5640资料/OV5640数据手册.pdf”)。需要注意的是,OV5640的数据手册并没有提供全部的寄存器描述,而大多数必要的寄存器配置在ov5640的软件应用手册中可以找到,可以结合这两个手册学习如何对OV5640进行配置。

1) 输出图像参数设置

接下来,我们介绍一下OV5640的ISP输入窗口设置、预缩放窗口设置和输出大小窗口设置,这几个设置与我们的正常使用密切相关,有必要了解一下,它们的设置关系如下图所示:

图 41.1.3 图像窗口设置

ISP输入窗口设置(ISP Input Size)允许用户设置整个传感器显示区域(physical pixel size,2632*1951,其中2592*1944像素是有效的),开窗范围从0*0~2632*1951都可以任意设置。也就是上图中的X_ADDR_ST(寄存器地址0x3800、0x3801)、Y_ADDR_ST(寄存器地址0x3802、0x3803)、X_ADDR_END(寄存器地址0x3804、0x3805)和Y_ADDR_END(寄存器地址0x3806、0x3807)寄存器。该窗口设置范围中的像素数据将进入ISP进行图像处理。

预缩放窗口设置(pre-scaling size)允许用户在ISP输入窗口的基础上进行裁剪,用于设置将进行缩放的窗口大小,该设置仅在ISP输入窗口内进行X/Y方向的偏移。可以通过X_OFFSET(寄存器地址0x3810、0x3811)和Y_OFFSET(寄存器地址0x3812、0x3813)进行配置。

输出大小窗口设置(data output size)是在预缩放窗口的基础上,经过内部DSP进行缩放处理,并将处理后的数据输出给外部的图像窗口,图像窗口控制着最终的图像输出尺寸。可以通过X_OUTPUT_SIZE(寄存器地址0x3808、0x3809)和Y_OUTPUT_SIZE(寄存器地址0x380A、0x380B)进行配置。注意:当输出大小窗口与预缩放窗口比例不一致时,图像将进行缩放处理(图像变形),仅当两者比例一致时,输出比例才是1:1(正常图像)。

图 41.1.3 图像窗口设置中,右侧data output size区域,才是OV5640输出给外部的图像尺寸,也就是显示在显示器或者液晶屏上面的图像大小。输出大小窗口与预缩放窗口比例不一致时,会进行缩放处理,在显示器上面看到的图像将会变形。

2)输出像素格式

OV5640支持多种不同的数据像素格式,包括YUV(亮度参量和色度参量分开表示的像素格式)、RGB(其中RGB格式包含RGB565、RGB555等)以及RAW(原始图像数据),通过寄存器地址0x4300配置成不同的数据像素格式。

由于摄像头采集的图像最终要通过LCD显示,故我们将OV5640摄像头输出的图像像素数据配置成RGB565格式。由上表(表 41.1.1)可知,将寄存器0x4300寄存器的Bit[7:4]设置成0x6即可。OV5640支持调节RGB565输出格式中各颜色变量的顺序,对于我们常见的应用来说,一般是使用RGB或BGR序列。我们在“OV7725摄像头RGB-LCD显示实验”的章节中介绍过,OV7725摄像头按照RGB的顺序输出,本章我们将OV5640输出的RGB565的颜色顺序和OV7725保持一致,将寄存器0x4300寄存器的Bit[3:0]设置成0x1。因此,“OV7725摄像头RGB-LCD显示实验”章节中的图像采集模块可以直接用来采集OV5640输出的图像。

3)彩条测试模式

图像传感器配置成彩条测试模式后,会输出彩色的条纹,方便测试图像传感器是否正常工作,通过配置寄存器0x503d的Bit[7]位打开和关闭彩条模式。当需要打开彩条模式时,寄存器0x503d配置成0x80,关闭时配置成0x00,下图为打开彩条模式后图像输出的条纹。

图 41.1.4 彩条模式下的图像条纹

4)LED闪光灯

当外界环境光较暗时,传感器采集图像会受到较大影响,此时可以通过打开LED补光灯来弥补光照不足所带来的影响,就像手机在夜晚拍照时也会打开闪光灯来提高图像质量。通过配置寄存器0x3016=0x02,0x301c=0x02来使能LED补光灯功能;配置寄存器0x3019=0x02打开闪光灯,0x3019=0x00关闭闪光灯。

5)图像输出时序

接下来,我们介绍一下OV5640的图像数据输出时序,首先我们简单介绍一些定义。

QSXGA,这里指:分辨率为2592*1944的输出格式,类似的还有:QXGA(2048*1536)、UXGA(1600*1200)、SXGA(1280*1024)、WXGA(1440*900)、WXGA(1280*800)、XGA(1024*768)、SVGA(800*600)、VGA(640*480)、QVGA(320*240)和QQVGA(160*120)等。

PCLK:像素时钟,一个PCLK时钟输出一个像素或者半个像素(像素数据的高8位或者低8位)。

VSYNC:帧同步信号。

HREF/HSYNC:行同步信号。

D[9:0]:像素数据,在RGB565格式中,只有高8位是有效的。

tPclk:一个时钟周期 。

tp:一个像素点的周期,在RGB565和YUV422输出格式下,tp=2*tPclk;Raw输出格式下,tp=tPclk。

下图为OV5640输出图像数据的行时序图。

图 41.1.5 OV5640行时序图

从上图可以看出,传感器在HREF为高电平的时候输出图像数据,当HREF变高后,每一个 PCLK时钟,输出一个8位或者10位像素数据。比如我们采用QSXGA时序,RGB565格式输出,tp=2*tPclk,每2个字节组成一个像素的颜色,这样每行总共输出2592*2个PCLK,也就是2592*2个字节。

再来看看帧时序(QSXGA模式,分辨率2592*1944),如下图所示:

图 41.1.6 OV5640 QSXGA帧时序

由上图可知,VSYNC的上升沿作为一帧的开始,高电平同步脉冲的时间为5688tp,紧接着等待48276tp时间后,HREF开始拉高,此时输出有效数据;HREF由2592tp个高电平和252tp个低电平构成;最后一行图像数据输出完成之后等待14544tp时间,一帧数据传输结束。所以输出一帧图像的时间实际上是tFrame = 5596992tp。

从OV5640的行时序图和帧时序图可以发现,其输出时序和OV7725是非常相似的,只是时间参数不同而已,大家可以参考“OV7725摄像头RGB-LCD显示实验”中帧时序的介绍来学习OV5640的输出时序。

41.2 实验任务

本节实验任务是使用ATK-DFPGL22G开发板及OV5640摄像头实现图像采集,并通过RGB-LCD接口驱动RGB-LCD液晶屏(支持目前正点原子推出的所有RGB-LCD屏),并实时显示出图像。

41.3 硬件设计

我们的ATK-DFPGL22G开发板上有一个摄像头扩展接口,该接口可以用来连接OV7725/OV5640等摄像头模块,摄像头扩展接口原理图如下图所示:

图 41.3.1 摄像头扩展接口原理图

ATK-OV5640是正点原子推出的一款高性能500W像素高清摄像头模块。该模块通过2*9排针(2.54mm间距)同外部连接,我们将摄像头的排针直接插在开发板上的摄像头接口即可。

模块自带有源晶振,用于产生24MHz时钟作为OV5640的输入时钟。模块的闪光灯(LEDI&LED2)由OV5640的STROBE引脚控制,用户可通过SCCB接口总线控制STROBE引脚输出高低电平,从而控制LED闪光灯的亮灭。用户在使用LED灯时不建议一直点亮或者点亮时间太长。因为LED闪光灯功率较高,发光强度较强,模块温度上升会比较快,会造成器件的可靠性降低,同时注意避免直接照射人眼。

我们在前面说过,OV5640在RGB565模式下只有高8位数据是有效的即D[9:2],而我们的摄像头排针上数据引脚的个数是8位。实际上,摄像头排针上的8位数据连接的就是OV5640传感器的D[9:2],所以我们直接使用摄像头排针上的8位数据引脚即可。

由于LCD接口和DDR3引脚数目较多且在前面相应的章节中已经给出它们的管脚列表,这里只列出摄像头相关管脚分配,如下表所示:

表 41.3.1 OV5640摄像头RGB-LCD显示实验管脚分配表 41.3.1 OV5640摄像头RGB-LCD显示实验管脚分配

OV5640摄像头与OV7725摄像头的约束几乎相同,只是C2引脚的cam_sgm_ctrl信号改为cam_pwdn信号,除了信号名改变了,其余约束没有任何改变,所以这里不再赘述约束文件。

41.4 程序设计

图 41.4.1是根据本章实验任务画出的系统框图。对比“OV7725摄像头RGB-LCD显示实验”的系统框图可以发现,本次实验只是把外设OV7725模块替换成了OV5640模块,将图像采集顶层模块替换成OV5640的驱动模块,并增加了一个摄像头图像分辨率设置模块,其余模块基本相同。图像采集顶层模块和OV5640驱动模块的区别在于,OV5640驱动模块删除了摄像头裁剪模块。这是由于OV5640摄像头分辨率的配置更灵活,可以与LCD屏的分辨率配置达成一致,因此本次实验不需要对摄像头图像进行裁剪。除此之外,本次实验还新增了一个摄像头图像分辨率设置模块,这个模块会根据LCD屏的ID,为OV5640驱动模块在配置摄像头分辨率时提供分辨率参数,也为DDR3控制器模块提供最大读写地址。时钟模块为OV5640驱动模块、LCD顶层模块以及DDR3控制器模块提供驱动时钟;OV5640驱动模块负责驱动外设OV5640摄像头和采集摄像头图像数据,并且把图像数据写入DDR3控制模块;DDR3控制模块负责将用户数据写入和读出片外DDR3存储器;LCD顶层模块负责驱动LCD屏和读取器件ID。

OV5640摄像头RGB-LCD显示系统框图如下图所示:

图 41.4.1 OV5640摄像头RGB-LCD显示系统框图

由上图可知,时钟模块(pll_clk)为LCD顶层模块、图像分辨率设置模块、DDR3控制模块以及OV5640驱动模块提供驱动时钟,OV5640驱动模块控制着传感器初始化的开始与结束,传感器初始化完成后图像采集模块将采集到的数据写入DDR3控制模块,LCD顶层模块从DDR3控制模块中读出数据,完成了数据的采集、缓存与显示。需要注意的是图像数据采集模块是在DDR3和传感器都初始化完成之后才开始输出数据的,避免了在DDR3初始化过程中向里面写入数据。

FPGA顶层模块(ov5640_lcd)例化了以下五个模块:时钟模块(pll_clk)、OV5640驱动模块(ov5640_dri)、摄像头图像分辨率设置模块(picture_size)、DDR3控制模块(ddr3_top)和LCD顶层模块(lcd_rgb_top)。

时钟模块(pll_clk):时钟模块通过调用PLL IP核实现,共输出2个时钟,频率分别为50Mhz时钟和100Mhz时钟。100Mhz时钟作为LCD顶层模块输出时钟的源时钟;50Mhz 时钟作为I2C驱动模块、DDR3控制模块和LCD顶层模块的驱动时钟。

OV5640驱动模块(ov5640_dri):OV5640驱动模块负责驱动OV5640 SCCB接口总线,将像素时钟驱动下的传感器输出的场同步信号、行同步信号以及8位数据转换成DDR3读写控制模块的写使能信号和16位写数据信号,完成对OV5640传感器图像的采集。

图像分辨率设置模块(picture_size):图像尺寸配置模块用于配置摄像头输出图像尺寸的大小,此外还完成了DDR3的读写结束地址设置。

DDR3控制模块(ddr3_top):DDR3读写控制器模块负责驱动DDR3片外存储器,缓存图像传感器输出的图像数据。该模块将DDR3 IP核复杂的读写操作封装成类似FIFO的用户接口,非常方便用户的使用。有关DDR3控制模块的详细介绍请大家参考“OV7725摄像头RGB-LCD显示实验”章节。

LCD顶层模块(lcd_rgb_top):LCD 顶层模块负责驱动LCD屏的驱动信号的输出,同时为其他模块提供屏体参数、场同步信号和数据请求信号。有关LCD驱动模块的详细介绍请大家参考“OV7725摄像头RGB-LCD显示实验”章节。

顶层模块大部分的代码在介绍“OV7725摄像头RGB-LCD显示实验”章节时已经介绍过了,这里不再详述,但还有部分代码做了改动,顶层改动的代码如下:

96 //摄像头图像分辨率设置模块 97 picture_size u_picture_size ( 98 .rst_n (rst_n ), 99 .clk (clk_50m ), 100 .ID_lcd (lcd_id ), //LCD的器件ID 101 102 .cmos_h_pixel (h_disp ), //摄像头水平分辨率 103 .cmos_v_pixel (v_disp ), //摄像头垂直分辨率 104 .total_h_pixel (total_h_pixel ), //水平总像素大小 105 .total_v_pixel (total_v_pixel ), //垂直总像素大小 106 .sdram_max_addr (ddr3_addr_max ) //ddr3最大读写地址 107 ); 108

这段代码是对图像分辨率设置模块的一个顶层例化,图像尺寸配置模块用于配置摄像头输出图像尺寸的大小,此外还完成了DDR3的读写结束地址设置。

在程序的第102和第103行,信号h_disp和信号v_disp是摄像头将要配置的分辨率,信号total_h_pixel和信号total_v_pixel连接到OV5640驱动模块,这两个信号的配置最终会影响摄像头的帧率。

在程序的第106行,表示的是写入一块DDR3的最大读写地址。

109 //ov5640 驱动 110 ov5640_dri u_ov5640_dri( 111 .clk (clk_50m ), 112 .rst_n (rst_n ), 113 114 .cam_pclk (cam_pclk ), 115 .cam_vsync (cam_vsync ), 116 .cam_href (cam_href ), 117 .cam_data (cam_data ), 118 .cam_rst_n (cam_rst_n ), 119 .cam_pwdn (cam_pwdn ), 120 .cam_scl (cam_scl ), 121 .cam_sda (cam_sda ), 122 123 .capture_start (sys_init_done ), 124 .cam_init_done (cam_init_done ), 125 .cmos_h_pixel (h_disp ), 126 .cmos_v_pixel (v_disp ), 127 .total_h_pixel (total_h_pixel ), 128 .total_v_pixel (total_v_pixel ), 129 .cmos_frame_vsync (cmos_frame_vsync), 130 .cmos_frame_href (cmos_frame_href ), 131 .cmos_frame_valid (cmos_frame_valid), 132 .cmos_frame_data (wr_data ) 133 );

这段代码是对OV5640驱动模块的一个顶层例化,负责驱动OV5640外设,采集图像等功能。

在程序的第114行至第121行,这几行的信号都是与外设OV5640相连的,负责驱动摄像头。

在程序的第123行,capture_start信号的作用是保证OV5640驱动模块在DDR3初始化没有完成之前不会对图像进行采集。

在程序的第125行至第128行,这四个信号是摄像头配置时需要的参数,使摄像头输出本次实验需要的行场分辨率和计算帧率的相关参数。

在程序的第131行和第132行,OV5640驱动模块输出的cmos_frame_valid(数据有效使能信号)和wr_data(有效数据)连接到DDR3控制模块,实现了图像数据的缓存。

图像尺寸配置模块用于配置摄像头输出图像尺寸的大小,此外还完成了DDR3的读写结束地址设置。图像分辨率设置模块的代码如下:

1 module picture_size ( 2 input rst_n , 3 input clk , 4 input [15:0] ID_lcd , 5 6 output [12:0] cmos_h_pixel , 7 output [12:0] cmos_v_pixel , 8 output [12:0] total_h_pixel , 9 output [12:0] total_v_pixel , 10 output [27:0] sdram_max_addr 11 ); 12 13 reg [12:0] cmos_h_pixel; 14 reg [12:0] cmos_v_pixel; 15 reg [12:0] total_h_pixel; 16 reg [12:0] total_v_pixel; 17 reg [27:0] sdram_max_addr; 18 19 //parameter define 20 parameter ID_4342 = 16'h4342; 21 parameter ID_7084 = 16'h7084; 22 parameter ID_7016 = 16'h7016; 23 parameter ID_1018 = 16'h1018; 24 25 //***************************************************** 26 //** main code 27 //***************************************************** 28 29 //配置摄像头输出尺寸的大小 30 always @(posedge clk or negedge rst_n) begin 31 if(!rst_n) begin 32 cmos_h_pixel


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有