资讯详情

【正点原子FPGA连载】 第三十五章 基于OV7725的PL以太网视频传输实验-摘自【正点原子】领航者ZYNQ之FPGA...

1)实验平台:正点原子领导者ZYNQ开发板 2)平台采购地址:https://item.taobao.com/item.htm?&id=606160108761 3)全套实验源码 手册 视频下载地址:http://www.openedv.com/thread-301505-1-1.html 4)正点原子FPGA感兴趣的同学可以加群讨论:99424016 5)关注正点原子微信官方账号,获取最新信息更新 在这里插入图片描述

第三十五章 基于OV7725的PL以太网视频传输实验

OV7725是OmniVision(豪威科技)公司生产的一个CMOS图像传感器主要用于玩具、安全监控、计算机多媒体等领域、安全监控、计算机多媒体等领域。本章将使用ZYNQ实现正确的开发板OV通过开发板采集7725数字图像PL将以太网接口发送到上位机实时显示。 本章分为以下章节: 35.1 简介 35.2 实验任务 35.3 硬件设计 35.4 程序设计 35.5 下载验证 35.1 简介 OV7725简介 OV7725是一种1/4英寸单芯片图像传感器,其感光阵列达到640*480,最快60fps图像采集的分辨率。图像处理功能集成在传感器内,包括自动曝光控制(AEC)、自动增益控制(AGC)与自动白平衡(AWB)等。同时,传感器具有较高的感光灵敏度,适用于低照度的应用下图为OV功能框图7725。

图 7.5.13.1 OV7725功能框图 从上图可以看出,感光阵列(image array)在XCLK图像采样由时钟驱动,输出640*480阵列的模拟数据;然后在时序发生器中模拟信号处理器(video timing generator)在控制下,算法处理模拟数据(analog processing);模拟数据处理完成后分成G(绿色)和R/B(红/蓝)两条通道经过AD转换器转换成数字信号后,并且通过DSP对相关图像进行处理,最终输出配置格式的10位视频数据流。模拟信号处理以及DSP通过寄存器等(registers)配置寄存器的接口是SCCB接口协议与接口兼容IIC协议。 SCCB(Serial Camera Control Bus,串行摄像头控制总线OV(OmniVision公司定义和开发的三线串行总线控制着摄像头的大部分功能,包括图像数据格式、分辨率和图像处理参数。OV为了减少传感器引脚的包装,公司现在SCCB大多数总线采用两线接口总线。 OV7725采用两线接口总线,包括SIO_C串行时钟输入线和SIO_D串行双向数据线相当于IIC协议的SCL信号线和SDA信号线。我们在前面提到过SCCB协议兼容IIC因为协议SCCB协议和IIC协议非常相似,相关IIC详细介绍协议请参考EEPROM读写实验章节。 SCCB如下图所示:

图 7.5.13.2 SCCB写传输协议 上图中的ID ADDRESS由7位器件地址和1位读写控制位组成 1:读),OV7725器件地址为7‘h因此,在写传输协议时,ID Address(W) = 8’h42(设备地址左移1位,低位补0);Sub-address为8位寄存器地址,在OV0725的数据手册定义为0x00~0xAC共有173个寄存器,有的寄存器可以重写,有的只读,只有可重写的寄存器才能正确写;Write Data为8位写数据,每个寄存器地址对应8位配置数据。上图中的第9位X表示Don’t Care(不用担心)OV7725)发出响应信号响应主机ID Address、Sub-address和Write Data是否传输完成,但从机可能不会发出响应信号,因此主机(此处指FPGA)不需要判断这里是否有回应,直接默认完成当前传输。 我们可以发现,SCCB和IIC写传输协议是极为相似的,只是在SCCB在写传输协议时,第九个不需要关心,IIC写传输协议作为响应位。SCCB阅读传输协议和IIC有些差异,在IIC在阅读传输协议时,将会有寄存器地址restart也就是重复开始的操作;而SCCB读取传输协议中没有重复开始的概念。写完寄存器地址后,启动总线停止信号。SCCB读传输协议。

图 7.5.13.3 SCCB读传输协议 从上图可以看出,SCCB阅读传输协议分为两部分。第一部分是编写设备地址和寄存器地址,即首先进行虚写操作。通过这种虚写操作,地址指针指向虚写操作中寄存器地址的位置。当然,虚写操作也可以通过上述写作传输协议来完成。第二部分是读取器件地址和数据。此时读取的数据是寄存器地址对应的数据。ID Address(R) = 8’h43(设备地址左移1位,低位补1位)。上图中的NA位于主机(这里指FPGA)产生,由于SCCB总线不支持连续读写,所以NA位置必须为高电平。 在OV7725正常工作前,必须先对传感器进行初始化,即通过配置寄存器使其工作在预期的工作模式,以及得到较好画质的图像。因为SCCB写传输协议和IIC几乎一样,所以我们可以直接使用IIC配置摄像头的驱动程序。当然,并非所有的寄存器都需要配置,许多寄存器可以使用默认值。OV公司提供了OV7725软件使用手册(OV7725 Software Application Note,附在开发板上的信息7_硬件资料/6_OV7725资料/OV7725 Software Application Note.pdf若某些寄存器不知道如何配置,可参考本手册,下表是本程序使用的关键寄存器的配置说明。 表 35.1.1 OV7725关键寄存器配置说明 地址 (HEX) 寄存器 默认值 (HEX) 详细说明 0x0C COM3 0x10 Bit[7]:保留 Bit[6]:水平镜像开关: Bit[5]:交换RGB输出模式B/R位置 Bit[4]:交换YUV输出模式Y/UV位置 Bit[3]:交换MSB/LSB位置 Bit[2]:电源休眠期间输出时钟三态选择 0:三态 1:非三态 Bit[1]:电源休眠期间输出数据三态选择 0:三态 1:非三态 Bit[0]:彩条测试使能 0x0D COM4 0x41 Bit[7:6]:PLL频率控制 00:旁路PLL(直通) 01: PLL 4x 02: PLL 6x 03: PLL 8x 0x11 CLKRC 0x00 Bit[6]:选择是否直接使用外部时钟 Bit内部PLL配置 F(internal clk) = F(input clk) * PLL multiplier/[(CLKRC[5:0] 1)* 2] 0x12 COM7 0x00 Bit[7]:SCCB寄存器复位 0:保持不变 1:复位所有寄存器 Bit[6]:0:VGA分辨率输出 1:QVGA分辨率输出 Bit[5]:BT.656协议开关 Bit[4]:Sensor RAW Bit[3:2]:RGB输出格式控制 00:GRB4:2:2 01:RGB565 10:RGB555 11: RGB444 Bit[1:0]:输出格式控制 00:YUV 01:Processed Bayer RAW 10:RGB 11:Bayer RAW 0x13 COM8 0xCF Bit[2]:选择是否开启自动增益AGC功能 Bit[1]:选择是否打开自动白平衡AWB功能 Bit[0]:选择是否打开自动曝光AEC功能 0x15 COM10 0x00 Bit[7]:反转输出图像数据 Bit[6]:切换HREF到HSYNC信号 Bit[5]:PCLK输出选项 0:PCLK时钟有效 1:行无有效信号时,PCLK无效 Bit[4]:翻转PCLK Bit[3]:翻转HREF Bit[1]:翻转VSYNC bit[0]:选择数据输出范围 0:10bit图像数据输出 1:高8bit图像数据输出 0x9B BRIGHT 0x00 亮度值补偿可以通过此值提高像素的亮度 OV7725寄存器较多,其他寄存器的描述可参考OV数据手册7725。 下图为OV7725的一些特点。

图 7.5.13.4 OV7725的特性 从上图可以看出,OV7725的输入时钟频率为10Mhz~48Mhz;SCCB总线的SIO_C最大时钟频率为400KHz;配置寄存器软件复位(寄存器地址0x12 Bit[7]位)和硬件复位(cam_rst_n引脚后需要等待最大1ms配置其他寄存器;每次配置寄存器后,需要最大300ms时间延迟,即10帧图像输出时间输出稳定的视频流。 OV7725支持各种不同分辨率图像的输出,包括VGA(640480)、QVGA(320240)以及CIF(分辨率为352的常用标准化图像格式288)到4030等任何尺寸。寄存器地址0x12(COM7)、0x17(HSTART)、0x18(HSIZE)、0x19(VSTRT)、0x1A(VSIZE)、0x32(HREF)、0x29(HoutSize)、0x2C(VOutSize)、0x2A(EXHCH)配置输出图像的分辨率。 OV7725支持多种不同的数据像素格式,包括YUV(亮度参数和色度参数分开表示像素格式)、RGB(其中RGB格式包含RGB565、RGB555等)以及8位的RAW(原始图像数据)和10位的RAW,通过寄存器地址0x12(COM7)配置不同的数据像素格式。 一般通过原始像素数据(如RGB565或者RGB888格式)来作为显示的数据会更加方便,因此我们将OV7725摄像头输出的图像像素数据配置成RGB565格式。本次实验采用OV7725支持的最大分辨率640*480,下图为摄像头输出的VGA帧模式时序图。

图 7.5.13.5 VGA帧模式输出时序图 在介绍时序图之前先了解几个基本的概念。 VSYNC:场同步信号,由摄像头输出,用于标志一帧数据的开始与结束。上图中VSYNC的高电平作为一帧的同步信号,在低电平时输出的数据有效。需要注意的是场同步信号是可以通过设置寄存器0x15 Bit[1]位进行取反的,即低电平同步高电平有效,本次实验使用的是和上图一致的默认设置; HREF/HSYNC:行同步信号,由摄像头输出,用于标志一行数据的开始与结束。上图中的HREF和HSYNC是由同一引脚输出的,只是数据的同步方式不一样。本次实验使用的是HREF格式输出,当HREF为高电平时,图像输出有效,可以通过寄存器0x15 Bit[6]进行配置。本次实验使用的是HREF格式输出; D[9:0]:数据信号,由摄像头输出,在RGB格式输出中,只有高8位D[9:2]是有效的; tPCLK:一个像素时钟周期; tp:单个数据周期,这里需要注意的是上图中左下角红框标注的部分,在RGB模式中,tp代表两个tPCLK(像素时钟)。以RGB565数据格式为例,RGB565采用16bit数据表示一个像素点,而OV7725在一个像素周期(tPCLK)内只能传输8bit数据,因此需要两个时钟周期才能输出一个RGB565数据; tLine:摄像头输出一行数据的时间,共784个tp,包含640tp个高电平和144tp个低电平,其中640tp为有效像素数据输出的时间。以RGB565数据格式为例,640tp实际上是6402=1280个tPCLK; 由图 7.5.13.5可知,VSYNC的上升沿作为一帧的开始,高电平同步脉冲的时间为4tLine,紧接着等待20tLine时间后,HREF开始拉高,此时输出有效数据;HREF由640tp个高电平和144tp个低电平构成;输出480行数据之后等待6tLine时间一帧数据传输结束。所以输出一帧图像的时间实际上是tFrame =(4 + 20 + 480 + 6)tLine = 510tLine。 由此我们可以计算出摄像头的输出帧率,以PCLK=25Mhz(周期为40ns)为例,计算出OV7725输出一帧图像所需的时间如下: 一帧图像输出时间:tFrame = 510tLine = 510784tp = 5107842tPCLK = 79968040ns = 31.9872ms; 摄像头输出帧率:1000ms/31.9872ms ≈ 31Hz。 如果把像素时钟频率提高到摄像头的最大时钟频率48Mhz,通过上述计算方法,摄像头的输出帧率约为60Hz。 下图为OV7725输出RGB565格式的时序图:

图 7.5.13.6 RGB565模式时序图 上图中的PCLK为OV7725输出的像素时钟,HREF为行同步信号,D[9:2]为8位像素数据。OV7725最大可以输出10位数据,在RGB565输出模式中,只有高8位是有效的。像素数据在HREF为高电平时有效,第一次输出的数据为RGB565数据的高8位,第二次输出的数据为RGB565数据的低8位,first byte和second byte组成一个16位RGB565数据。由上图可知,数据是在像素时钟的下降沿改变的,为了在数据最稳定的时刻采集图像数据,所以我们需要在像素时钟的上升沿采集数据。 图像传输简介 随着图像技术、监控技术的发展,通信的数据量越来越大,这无疑对数据传输系统的实时性、稳定性和高效性都提出了苛刻的要求。对于大量数据的高速传输,一般使用以太网或者USB传输方案,而以太网相比于USB,有着传输距离更远的优势。为了能够满足视频在高帧率、高分辨率下实时传输,传统的百兆以太网已不能满足需求,此时需要通过千兆以太网进行传输。本章将使用开发板上的千兆以太网接口传输视频,并通过上位机实时显示。 以太网实时传输图像采用的传输层协议有TCP和UDP两种。TCP协议能为两个端点间的数据传输提供相对可靠的保障,这种保障是通过一个握手机制实现的。当数据发送给接收者时,接收者要检查数据的正确性,当接收者接收到正确数据后给发送者一个确认报文信号,发送者只有接收到接收者的确认报文信号后才能发送下一个数据块。如果没有接收到确认报文,这个数据块就必须要重新发送。尽管这种机制对传输数据来说是非常合理的,但当用它在以太网视频实时传输时就会引发很多问题。首先就是延迟问题,在传输信道丢包率较高时,TCP的传输质量下滑严重,重传拥塞导致视频延时非常大,失去实时互通的意义。而UDP相比于TCP能提供更高的吞吐量和较低的延迟,非常适合低延时的视频传输场合。 UDP性能的提高是以不能保障数据完整性为代价的,它不能对所传数据提供担保,有时会出现数据丢包的现象。为了降低丢包对视频显示带来的影响,我们为每帧图像添加一个帧头,用于标志一帧图像的开始。上位机解析到图像帧头之后,接下来将接收到的像素数据重新放到图像显示区域的起始位置,保证了在视频传输过程中,即使出现丢包的现象,视频也能恢复到正常显示的画面。 35.2 实验任务 本节实验任务是使用领航者ZYNQ开发板及OV7725摄像头实现图像采集,并通过开发板上的PL以太网接口发送给上位机实时显示。 35.3 硬件设计 领航者Zynq开发板上有一个摄像头扩展接口,该接口可以用来连接OV7725/OV5640等摄像头模块。由于SCCB接口通信需要接上拉电阻,因此,将CMOS_SCL信号和CMOS_SDA信号连接上拉电阻,原理图如图 7.5.13.1所示:

图 7.5.13.1 摄像头扩展接口原理图 ATK-OV7725是正点原子推出的一款高性能30W像素高清摄像头模块。该模块通过2*9排针(2.54mm间距)同外部连接,我们将摄像头的排针直接插在开发板上的摄像头接口即可,模块外观如图 7.5.13.2所示:

图 7.5.13.2 ATK-OV7725摄像头模块实物图 我们在前面说过,OV7725在RGB565模式中只有高8位数据是有效的即D[9:2],而我们的摄像头排针上数据引脚的个数是8位。实际上,摄像头排针上的8位数据连接的就是OV7725传感器的D[9:2],所以我们直接使用摄像头排针上的8位数据引脚即可。 需要注意的是,由图 7.5.13.1可知,摄像头扩展口的第18个引脚定义为CMOS_PWDN,而我们的OV7725摄像头模块的PWDN引脚固定为低电平,也就是一直处于正常工作模式。OV7725摄像头模块的第18个引脚定义为SGM_CTRL,这个引脚是摄像头驱动时钟的选择引脚。OV7725摄像头模块内部自带晶振的,当SGM_CTRL引脚为低电平时,选择使用摄像头的外部时钟,也就是FPGA需要输出时钟给摄像头;当SGM_CTRL引脚为高电平时,选择使用摄像头的晶振提供时钟。本次实验将SGM_CTRL引脚驱动为高电平,这样就不用为摄像头提供驱动时钟,即不用在CMOS_XCLK引脚上输出时钟。 由于PL以太网引脚数目较多,且在前面相应的章节中已经给出它们的管脚列表,这里只列出摄像头相关管脚分配, 如下表所示: 表 35.3.1 OV7725摄像头管脚分配 信号名 方向 管脚 端口说明 IO电平 cam_pclk input W14 cmos 数据像素时钟 LVCMOS33 cam_vsync input U12 cmos 场同步信号 LVCMOS33 cam_href input T12 cmos 行同步信号 LVCMOS33 cam_rst_n output P14 cmos 复位信号 LVCMOS33 cam_sgm_ctrl output V15 cmos 时钟选择信号 LVCMOS33 cam_data[0] input R14 cmos 数据 LVCMOS33 cam_data[1] input U13 cmos 数据 LVCMOS33 cam_data[2] input V13 cmos 数据 LVCMOS33 cam_data[3] input U15 cmos 数据 LVCMOS33 cam_data[4] input U14 cmos 数据 LVCMOS33 cam_data[5] input W13 cmos 数据 LVCMOS33 cam_data[6] input V12 cmos 数据 LVCMOS33 cam_data[7] input Y14 cmos 数据 LVCMOS33 emio_sccb_tri_io[0] output T10 cmos SCCB_SCL线 LVCMOS33 emio_sccb_tri_io[1] inout T11 cmos SCCB_SDA线 LVCMOS33 相关的管脚约束如下所示: #系统时钟和复位

create_clock -period 20.000 -name sys_clk [get_ports sys_clk]
create_clock -period 8.000 -name eth_rxc [get_ports eth_rxc]
set_property -dict { 
        PACKAGE_PIN U18 IOSTANDARD LVCMOS33} [get_ports sys_clk]
set_property -dict { 
        PACKAGE_PIN N16 IOSTANDARD LVCMOS33} [get_ports sys_rst_n]

set_property -dict { 
        PACKAGE_PIN G15 IOSTANDARD LVCMOS33} [get_ports eth_rst_n]
set_property -dict { 
        PACKAGE_PIN K17 IOSTANDARD LVCMOS33} [get_ports eth_rxc]
set_property -dict { 
        PACKAGE_PIN E17 IOSTANDARD LVCMOS33} [get_ports eth_rx_ctl]
set_property -dict { 
        PACKAGE_PIN B19 IOSTANDARD LVCMOS33} [get_ports { 
        eth_rxd[0]}]
set_property -dict { 
        PACKAGE_PIN A20 IOSTANDARD LVCMOS33} [get_ports { 
        eth_rxd[1]}]
set_property -dict { 
        PACKAGE_PIN H17 IOSTANDARD LVCMOS33} [get_ports { 
        eth_rxd[2]}]
set_property -dict { 
        PACKAGE_PIN H16 IOSTANDARD LVCMOS33} [get_ports { 
        eth_rxd[3]}]

set_property -dict { 
        PACKAGE_PIN B20 IOSTANDARD LVCMOS33} [get_ports eth_txc]
set_property -dict { 
        PACKAGE_PIN K18 IOSTANDARD LVCMOS33} [get_ports eth_tx_ctl]
set_property -dict { 
        PACKAGE_PIN D18 IOSTANDARD LVCMOS33} [get_ports { 
        eth_txd[0]}]
set_property -dict { 
        PACKAGE_PIN C20 IOSTANDARD LVCMOS33} [get_ports { 
        eth_txd[1]}]
set_property -dict { 
        PACKAGE_PIN D19 IOSTANDARD LVCMOS33} [get_ports { 
        eth_txd[2]}]
set_property -dict { 
        PACKAGE_PIN D20 IOSTANDARD LVCMOS33} [get_ports { 
        eth_txd[3]}]

#CAMERA
create_clock -period 40.000 -name cmos_pclk [get_ports cam_pclk]
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets cam_pclk_IBUF]
set_property -dict { 
        PACKAGE_PIN W14 IOSTANDARD LVCMOS33} [get_ports cam_pclk]
set_property -dict { 
        PACKAGE_PIN P14 IOSTANDARD LVCMOS33} [get_ports cam_rst_n]
set_property -dict { 
        PACKAGE_PIN V15 IOSTANDARD LVCMOS33} [get_ports cam_sgm_ctrl]
set_property -dict { 
        PACKAGE_PIN R14 IOSTANDARD LVCMOS33 IOB TRUE} [get_ports { 
        cam_data[0]}]
set_property -dict { 
        PACKAGE_PIN U13 IOSTANDARD LVCMOS33 IOB TRUE} [get_ports { 
        cam_data[1]}]
set_property -dict { 
        PACKAGE_PIN V13 IOSTANDARD LVCMOS33 IOB TRUE} [get_ports { 
        cam_data[2]}]
set_property -dict { 
        PACKAGE_PIN U15 IOSTANDARD LVCMOS33 IOB TRUE} [get_ports { 
        cam_data[3]}]
set_property -dict { 
        PACKAGE_PIN U14 IOSTANDARD LVCMOS33 IOB TRUE} [get_ports { 
        cam_data[4]}]
set_property -dict { 
        PACKAGE_PIN W13 IOSTANDARD LVCMOS33 IOB TRUE} [get_ports { 
        cam_data[5]}]
set_property -dict { 
        PACKAGE_PIN V12 IOSTANDARD LVCMOS33 IOB TRUE} [get_ports { 
        cam_data[6]}]
set_property -dict { 
        PACKAGE_PIN Y14 IOSTANDARD LVCMOS33 IOB TRUE} [get_ports { 
        cam_data[7]}]
set_property -dict { 
        PACKAGE_PIN U12 IOSTANDARD LVCMOS33} [get_ports cam_vsync]
set_property -dict { 
        PACKAGE_PIN T12 IOSTANDARD LVCMOS33} [get_ports cam_href]
set_property -dict { 
        PACKAGE_PIN T10 IOSTANDARD LVCMOS33} [get_ports cam_scl]
set_property -dict { 
        PACKAGE_PIN T11 IOSTANDARD LVCMOS33} [get_ports cam_sda]

35.4 程序设计 OV7725在VGA(分辨率为640480)帧模式下,以RGB565格式输出最高帧率可达60Hz,每秒钟输出的数据量达到6064048016bit = 294912000bit = 281.25Mbit。我们FPGA开发板上的PHY芯片类型为千兆以太网,理论上最大传输速率为1000Mbit/s,加上帧头、CRC校验以及帧间隙带来的额外开销,实际上能达到的最大传输速率比理论上最大传输速率低。尽管实际传输速率低于1000Mbit/s,但实时传输OV7725摄像头的图像完全没有压力,可以满足带宽要求,因此本次实验不需要通过片外存储器缓存图像,仅将图像数据先经过FIFO进行缓存,然后通过以太网接口进行发送即可。 根据实验任务,我们可以大致规划出系统的控制流程:时钟模块用于为IIC驱动模块、以太网顶层模块和开始传输控制模块提供驱动时钟。I2C驱动模块和I2C配置模块用于初始化OV7725图像传感器;摄像头采集模块负责采集摄像头图像数据,并且把图像数据连接至图像数据封装模块,图像数据封装模块将输入的图像数据进行位拼接,并添加图像的帧头和行场分辨率;以太网顶层模块实现以太网数据的收发;开始传输控制模块控制以太网顶层模块开始/停止发送数据。 OV7725的以太网视频传输系统框图如下图所示:

图 7.5.13.1 系统框图 顶层模块的原理图如下图所示:

图 7.5.13.2 顶层模块原理图 FPGA顶层模块(ov7725_udp_pc)例化了以下七个模块:时钟模块(clk_wiz_0)、I2C驱动模块(i2c_dri)、I2C配置模块(i2c_ov7725_rgb565_cfg)、摄像头图像采集模块(cmos_capture_data)、开始传输控制模块(start_transfer_ctrl)、图像数据封装模块(img_data_pkt)和以太网顶层模块模块(eth_top)。 时钟模块(clk_wiz_0):时钟IP核模块通过调用MMCM IP核来实现,总共输出2个时钟,频率分别为50Mhz和200Mhz时钟。50Mhz时钟作为I2C驱动模块的驱动时钟;200Mhz时钟作为IDELAYCTRL源语的参考时钟。 I2C驱动模块(i2c_dri):I2C驱动模块负责驱动OV7725 SCCB接口总线,用户可根据该模块提供的用户接口可以很方便的对OV7725的寄存器进行配置,该模块和“EEPROM读写实验”章节中用到的I2C驱动模块为同一个模块,有关该模块的详细介绍请大家参考“EEPROM读写实验”章节。 I2C配置模块(i2c_ov7725_rgb565_cfg):I2C配置模块的驱动时钟是由I2C驱动模块输出的时钟提供的,这样方便了I2C驱动模块和I2C配置模块之间的数据交互。该模块寄存需要配置的寄存器地址、数据以及控制初始化的开始与结束,同时该模块输出OV7725的寄存器地址和数据以及控制I2C驱动模块开始执行的控制信号,直接连接到I2C驱动模块的用户接口,从而完成对OV7725传感器的初始化。 摄像头图像采集模块(cmos_capture_data):摄像头采集模块在像素时钟的驱动下将传感器输出的场同步信号、行同步信号以及8位数据转换成16位数据信号,完成对OV7725传感器图像的采集。 开始传输控制模块(start_transfer_ctrl):该模块解析以太网顶层模块接收到的数据,如果收到1个字节的ASCII码“1”,则表示以太网开始传输图像数据;如果收到1个字节的ASCII码“0”,则表示以太网停止传输图像数据。 图像数据封装模块(img_data_pkt):图像数据封装模块负责将输入16位的图像数据,拼接成32位数据,以及添加图像数据的帧头和行场分辨率。该模块控制着以太网发送模块发送的字节数,单次发送一行图像数据的字节数,模块内部例化了一个异步FIFO模块,用于缓存待发送的图像数据。 以太网顶层模块(eth_top):以太网顶层模块实现以太网通信的收发功能,有关该模块的详细介绍请大家参考“以太网UDP测试实验”章节。 顶层模块部分代码如下:

1   module ov7725_udp_pc(
2       input              sys_clk     , //系统时钟 
3       input              sys_rst_n   , //系统复位信号,低电平有效 
4       //以太网接口
5       input              eth_rxc     , //RGMII接收数据时钟
6       input              eth_rx_ctl  , //RGMII输入数据有效信号
7       input       [3:0]  eth_rxd     , //RGMII输入数据
8       output             eth_txc     , //RGMII发送数据时钟 
9       output             eth_tx_ctl  , //RGMII输出数据有效信号
10      output      [3:0]  eth_txd     , //RGMII输出数据 
11      output             eth_rst_n   , //以太网芯片复位信号,低电平有效 
12  
13      //摄像头接口
14      input              cam_pclk    , //cmos 数据像素时钟
15      input              cam_vsync   , //cmos 场同步信号
16      input              cam_href    , //cmos 行同步信号
17      input     [7:0]    cam_data    , //cmos 数据
18      output             cam_rst_n   , //cmos 复位信号,低电平有效
19      output             cam_sgm_ctrl, //cmos 时钟选择信号, 1:使用摄像头自带的晶振
20      output             cam_scl     , //cmos SCCB_SCL线
21      inout              cam_sda       //cmos SCCB_SDA线 
22  );
23  
24  //parameter define
25  //开发板MAC地址 00-11-22-33-44-55
26  parameter  BOARD_MAC = 48'h00_11_22_33_44_55;     
27  //开发板IP地址 192.168.1.10
28  parameter  BOARD_IP  = { 
        8'd192,8'd168,8'd1,8'd10};  
29  //目的MAC地址 ff_ff_ff_ff_ff_ff
30  parameter  DES_MAC   = 48'hff_ff_ff_ff_ff_ff;    
31  //目的IP地址 192.168.1.102 
32  parameter  DES_IP    = { 
        8'd192,8'd168,8'd1,8'd102};
33  
34  parameter  SLAVE_ADDR = 7'h21 ; //OV7725的器件地址7'h21
35  parameter  BIT_CTRL   = 1'b0          ;  //OV7725的字节地址为8位 0:8位 1:16位
36  parameter  CLK_FREQ   = 26'd50_000_000;  //i2c_dri模块的驱动时钟频率
37  parameter  I2C_FREQ   = 18'd250_000   ;  //I2C的SCL时钟频率,不超过400KHz

在代码的第24至32行定义了四个参量:开发板MAC地址BOARD_MAC,开发板IP地址 BOARD_IP,目的MAC地址DES_MAC(这里指PC MAC地址),目的IP地址 DES_IP(PC IP地址)。开发板的MAC地址和IP地址是我们随意定义的,只要不和目的MAC 地址和目的IP地址一样就可以,否则会产生地址冲突。目的MAC地址这里写的是公共MAC 地址(48’hff_ff_ff_ff_ff_ff),也可以修改成电脑网口的MAC地址,DES_IP是对应电脑以太网的IP地址,这里定义的四个参数是向下传递的,需要修改MAC地址或者IP地址时直接在这里修改即可,而不用在以太网顶层模块里面修改。 在代码的第34行定义了OV7725的器件地址,其器件地址为7’h21;第35行定义了寄存器地址的位宽,BIT_CTRL=0表示地址位宽为8位,BIT_CTRL=1表示地址位宽为16位。因为OV7725的地址位宽为8位,所以BIT_CTRL设置为0。第36行和第37行分别定义了i2c_dri模块的驱动时钟频率和I2C的SCL时钟频率。

70  assign  rst_n = sys_rst_n & locked;
71  //不对摄像头硬件复位,固定高电平
72  assign  cam_rst_n = 1'b1;
73  //cmos 时钟选择信号, 1:使用摄像头自带的晶振
74  assign  cam_sgm_ctrl = 1'b1;
75  
76  //例化MMCM
77  clk_wiz_0 u_clk_wiz_0
78     (
79      .clk_out1    (clk_50m),  
80      .clk_out2    (clk_200m), 
81      .reset       (~sys_rst_n),  
82      .locked      (locked),       
83      .clk_in1     (sys_clk)
84      );      
85  
86  //I2C配置模块 
87  i2c_ov7725_rgb565_cfg u_i2c_cfg(
88      .clk           (i2c_dri_clk),
89      .rst_n         (rst_n),
90      .i2c_done      (i2c_done),
91      .i2c_exec      (i2c_exec),
92      .i2c_data      (i2c_data),
93      .init_done     (cam_init_done)
94      );    
95  
96  //I2C驱动模块
97  i2c_dri 
98     #(
99      .SLAVE_ADDR  (SLAVE_ADDR),               //参数传递
100     .CLK_FREQ    (CLK_FREQ  ),              
101     .I2C_FREQ    (I2C_FREQ  )                
102     ) 
103    u_i2c_dri(
104     .clk         (clk_50m   ),   
105     .rst_n       (rst_n     ),   
106     //i2c interface
107     .i2c_exec    (i2c_exec  ),   
108     .bit_ctrl    (BIT_CTRL  ),   
109     .i2c_rh_wl   (1'b0),                     //固定为0,只用到了IIC驱动的写操作 
110     .i2c_addr    (i2c_data[15:8]),   
111     .i2c_data_w  (i2c_data[7:0]),   
112     .i2c_data_r  (),   
113     .i2c_done    (i2c_done  ),   
114     .scl         (cam_scl   ),   
115     .sda         (cam_sda   ),   
116     //user interface
117     .dri_clk     (i2c_dri_clk)               //I2C操作时钟
118 );
119 
120 //摄像头数据采集模块
121 cmos_capture_data u_cmos_capture_data(
122 
123     .rst_n              (rst_n & cam_init_done),
124     .cam_pclk           (cam_pclk),   
125     .cam_vsync          (cam_vsync),
126     .cam_href           (cam_href),
127     .cam_data           (cam_data),           
128     .cmos_frame_vsync   (cmos_frame_vsync),
129     .cmos_frame_href    (),
130     .cmos_frame_valid   (img_data_en),     
131     .cmos_frame_data    (img_data)             
132     );

OV7725摄像头配置模块和IIC驱动模块实现对OV7725摄像头的初始化,在初始化完成后拉高cam_init_done信号,此时开始通过摄像头数据采集模块接收摄像头输出的图像数据(如程序中第123行代码所示),将输入的8位数据转换成16位RGB565数据。

134 //开始传输控制模块 
135 start_transfer_ctrl u_start_transfer_ctrl(
136     .clk                (eth_rx_clk),
137     .rst_n              (rst_n),
138     .udp_rec_pkt_done   (udp_rec_pkt_done),
139     .udp_rec_en         (udp_rec_en      ),
140     .udp_rec_data       (udp_rec_data    ),
141     .udp_rec_byte_num   (udp_rec_byte_num),
142 
143     .transfer_flag      (transfer_flag)      //图像开始传输标志,1:开始传输 0:停止传输
144     );       
145      
146 //图像封装模块 
147 img_data_pkt u_img_data_pkt(    
148     .rst_n              (rst_n),              
149    
150     .cam_pclk           (cam_pclk),
151     .img_vsync          (cmos_frame_vsync),
152     .img_data_en        (img_data_en),
153     .img_data           (img_data),
154     .transfer_flag      (transfer_flag),            
155     .eth_tx_clk         (eth_tx_clk     ),
156     .udp_tx_req         (udp_tx_req     ),
157     .udp_tx_done        (udp_tx_done    ),
158     .udp_tx_start_en    (udp_tx_start_en),
159     .udp_tx_data        (udp_tx_data    ),
160     .udp_tx_byte_num    (udp_tx_byte_num)
161     );  
162 
163 //以太网顶层模块 
164 eth_top  #(
165     .BOARD_MAC     (BOARD_MAC),              //参数例化
166     .BOARD_IP      (BOARD_IP ),          
167     .DES_MAC       (DES_MAC  ),          
168     .DES_IP        (DES_IP   )          
169     )          
170     u_eth_top(          
171     .sys_rst_n       (rst_n     ),           //系统复位信号,低电平有效 
172     .clk_200m        (clk_200m), 
173     //以太网RGMII接口 
174     .eth_rxc         (eth_rxc   ),           //RGMII接收数据时钟
175     .eth_rx_ctl      (eth_rx_ctl),           //RGMII输入数据有效信号
176     .eth_rxd         (eth_rxd   ),           //RGMII输入数据
177     .<

标签: 05n直流三线传感器d40传感器安防专用直通连接器wl1260单点式传感器h8a传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台