基于FPGA的图像采集系统设计与实现
摘 要
现在是科技迅速发展的年代,数字图像处理技术在这个年代中得到了迅猛的发展并在各行各业得到了广泛的应用。可编程逻辑器件(FPGA)凭借其较低的开发成本、较高的并行处理速度、较大的灵活性及其较短的开发周期等特点,在图像处理系统中有独特的优势。
针对视频图像采集的可靠性和实时性,本设计采用Altera公司生产的CycloneⅡEP2C8Q208C8NK芯片,先由CCD图像传感器采集模拟信号,在经过芯片TVP5150将模拟量转换为标准的YUV4:2:2的数据信号,把数据信号输入到FPGA芯片中并在其中将该数据转换到RGB色域后在输出到ADV7123芯片进行D/A转换,最后经过VGA接口电路把处理过的图像呈现在显示屏上。经过相关的调试工作,系统通用性比较好,并且移动性能也不错。
该系统的软件部分采用自顶向下的设计方法,模块化设计思想,硬件语言编程,只修改源程序,不必更改硬件电路,就可实现在线编程,实时控制,从而有效地减少系统的体积,不但增加了系统可靠性,降低研制成本,并且能够对控制逻辑进行修改升级,十分灵活。该系统包括三个功能模块:图像采集模块、图像处理模块、图像显示模块。
关键词:FPGA;TVP5150;RGB色域;ADV7123芯片
Image acquisition system based on FPGA design and
implementation
Abstract
It is the rapid development of science and technology, digital image processing technology has been rapid development in this era and has been widely used in all walks of life, and the maturity of FPGA technology has changed the commonly used parallel computer or digital signal processor (DSP), a special integrated circuit (ASIC) as the embedded processor usage. Programmable logic device (FPGA) with its low cost, high parallel processing speed, flexibility and short development cycle and other characteristics, has its unique advantages in image processing system. The project demand, this paper presents a solution of image acquisition and processing system based on FPGA, and the use of low cost and high performance of Altera company's CyclonelI series FPGA EP2C8Q208C8N as the core, design and development of integrated system of hardware and software of image acquisition and processing.
In view of the reliability of video image acquisition and real-time performance, this paper describes how to FPGA for video acquisition system control. Using Cyclone Ⅱ EP2C8Q208C8NK chip produced by Altera company, is responsible for receiving and processing video data from the TVP5150 decoding, converts the data into RGB color gamut in the output to the ADV7123 chip. After debugging, the system better generality, and mobile performance is also good.
Keywords: FPGA;TVP5150;RGB color gamut;ADV7123 chip
目 录
1 前言 .......................................... 1
1.1 课题背景与意义 ............................... 1 1.2 研究的现状及特点 .............................. 2 1.3 研究的主要内容 ............................... 2
2 图像采集系统的硬件电路设计 .................... 3
2.1 采集系统硬件的总体设计 ....................... 3 2.2 FPGA核心模块 .................................... 5 2.3 外围电路 ..................................... 6 2.4 图像采集电路 .................................... 7 2.4.1 图像传感器 .................................... 7 2.4.2 A/D转换电路 ................................... 8 2.5 图像显示电路 .................................... 8
3 图像采集系统的软件设计 ....................... 11 3.1 系统的设计环境 ............................. 11
3.2 设计的主要流程 .............................. 12 3.3 设计内部数据量的变换 ......................... 12 3.3.1 IIC数据总线 .................................. 12
4 调试 ......................................... 17
参考文献 ........................................ 18 致谢 ............................................ 19 附录 ............................................ 20
1 前言
1.1 课题背景与意义
随着多媒体技术在各个应用领域不断普及,用户会不断要求新产品具有更大的图像容量、更高的图像质量和更快的图像处理速度,这为图像的存储和处理提出了更高的要求。在数字图像处理可视电话通信、数字电视等应用中,遇到的首要难题就是数据量过大,导致图像传输和存储成问题。现场可编程门阵列(FPGA),与传统逻辑电路和门阵列相比FPGA具有不同的结构它增强了电路设计的灵活性。不但降低了开发成本,而且也减小了设计风险,并且充分挖掘图像处理算法中的并行性,在较低主频下能获得可观的执行速度。因此,在信号处理方面得到了广泛的应用。
FPGA作为系统以及图像采集处理板卡的核心器件,外围器件的电路和功能已经得到尽可能的简化,许多外围的功能器件的接口都不需要单独的接口芯片来完成,均由FPGA来实现.整个系统中仅仅需要FPGA以及FPGA配置芯片、SDRAM、PCI接口芯片三个主要的芯片,整体上看提高了电路的稳定性,而且其先进的开发工具使整个系统的设计调试周期大大缩短。因此FPGA内部逻辑设计就成为图像采集处理系统设计的核心和关键。
1.2 研究的现状及特点
20世纪20年代,图像处理首次得到应用。20世纪60年代中期,随电子计算机的发展得到普遍应用。60年代末,图像处理技术不断完善,逐渐成为一个新兴的学科。利用数字图像处理主要是为了修改图形,改善图像质量,或是从图像中提起有效信息,还有利用数字图像处理可以对图像进行体积压缩,便于传输和保存。数字图像处理主要研究以下内容:傅立叶变换、小波变换等各种图像变换;对图像进行编码和压缩;采用各种方法对图像进行复原和增强;对图像进行分割、描述和识别等。随着技术的发展,数字图像处理主要应用于通讯技术、宇宙探索遥感技术和生物工程等领域。数字图像处理因易于实现非线性处理,处理程序和处理参数可变,故是一项通用性强、精度高、处理方法灵活、信息保存、传送可靠的图像处理技术。主要用于图像变换、量测、模式识别、模拟以及图像产生,并广泛应用在遥感、宇宙观测、影像医学、通信、刑侦及多种工业领域[1]。
而在对图像处理这一技术上FPGA具有以下几种特点: (1):高性能,可以在一片FPGA中完成多种处理功能
(2):灵活性高使产品快速面市,方便产品跟新,满足不断发展的需求 (3):低开发成本并且结构化容易操作
(4):不会过时,其拥有非常广泛的客户基础,而且FPGA可以很容易的从一个工作节点移植到下一个工作节点。
1
1.3 研究的主要内容
先利用CCD图像传感器采集图像模拟量输入给TVP5150芯片,再利用Altera公司的CyclonelI系列FPGA EP2C8Q208C8N芯片,负责接受和处理来自TVP5150解码后的视频数据,将该数据转换到RGB色域后在输出到ADV7123芯片再传输到液晶显示器。在系统设计过程中需要研究以下问题:
(1):制定图像采集系统的整体的设计方案.。
(2):设计图像采集模块,图像处理模块,图像显示模块,和FPGA主控制模块。 (3):程序的编译与仿真,通过对程序的编译与仿真实现了对FPGA芯片控制,将数据转换到RGB色域后输出。
系统设计过程中主要通过Quartus9.1的开发环境编译系统的程序,然后使用下载软件将程序下载到单片机运行,通过运行情况修改程序再进行调试。调试的是从单个模块开始,然后进行综合调试至系统功能的实现。
2
2 图像采集系统的硬件电路设计
2.1 采集系统硬件的总体设计
如图2-1所示:该系统包括几个功能模块:图像采集模块、图像处理模块、图像显示模块。其中图像采集模块主要由外接摄像头和TVP5150 解码芯片组成,完成视频信号的采集和硬件解码能,并以ITU-656 标准输出YUV 4:2:2 信号;图像处理模块选用的FPGA 是Altera 公司生产的Cyclone ⅡEP2C8Q208C8N 芯片构成,完成系统控制,视频信号的采集以及后续处理等工作;图像显示模块主要由ADV7123 芯片、VGA 接口和CRT 显示器等组成,主要完成视频信号的数模转换,输出并显示视频信号。
CCD摄像头 AD转换及视频解码 FPGA解码 色域转换 控制A/D芯片 控制D/A芯片 控制VGA输出 D/A转换 VGA接口 CRT显示
图2-1 图像采集系统的硬件总体设计
在图2-1所示视频图像的采集与处理过程中,FPGA作为整个系统的控制与处理核心,主要是通过该芯片的I/O 管脚来控制数据采集芯片TVP5150和高速D/A 转换芯片ADV7123,并且负责接受和处理来自TVP5150解码后的视频数据,将该数据转换到RGB 色域后输出到ADV7123芯片。实物如图2-2所示:
3
图2-2 硬件实物
2.2 FPGA核心模块
在充分考虑性价比和设计功能的基础上,决定采用Altera公司CycloneII系列的FPGA,它是Altera公司最新一代SRAMI艺、中等规模的低成本FPGA,与Stratix结构类似,是目前的主流产品。它支持各种单端I/O标准(如LVlvrL、LVCOS、和SSTL.2/3),通过LVDS和RSDS标准提供多达227个通道的差分I/O支持,LVDS通道高达640Mbps。它具有生成时钟锁相环以及DDR、SDR和快速RAM(FCRAM)存储器所需的专用双数据率(DDR)接口等。它完全支持Altera公司的NiosII处理器,支持通过SOPC(可编程片上系统)软件对这个系列的芯片进行专门优化,使其性能得到进一步提高。其芯片如图2-3所示:
4
图2-3 核心芯片引脚图
2.3 外围电路
外围电路包括多种电路模块例如电源电路模块,晶振电路模块,复位电路模块等等。在众多电路模块中最重要的是电源模块,电源模块是整个系统的基础,它为其它各个硬件系统模块提供其所需的工作电源。而且由于系统采用的芯片较多,需要电源模块提供多种不同的电源信号,例如为数字电路芯片提供数字电压,而对模拟电力模块提供模拟电压,根据此要求电源模块的设计就需要能够输出多种不同标准的电压。
所以采用AC/DC电源模块,把交流220V转换成5V直流电再采用转换电路,转变成系统需要的电源,如数字电压1.2V、1.5V、2.5V、3.3V等,模拟电压2.5V。其电源转换电路如图2-4所示:
5
图2-4 电源电路图
2.4 图像采集电路
2.4.1 图像传感器
目前来讲图像传感器可分为模拟视频摄像头和数字视频摄像头、彩色摄像头和黑白摄像头、CMOS图像传感器和CCD图像传感器。其中CCD图像传感器以及CMOS图像传感器是当今常用的两种模拟/数字图像传感器。
在CCD与CMOS进行对比基本上两者都是利用矽感光二极体(photodiode)进行光与电的转换。光线越强、电力越强;反之,光线越弱、电力也越弱的道理,将光影像转换为电子数字信号。由于构造上的基本差异,我们可以表列出两者在性能上的表现之不同。CCD的特色在于充分保持信号在传输时不失真(专属通道设计),透过每一个像素集合至单一放大器上再做统一处理,可以保持资料的完整性;CMOS的制程较简单,没有专属通道的设计,因此必须先行放大再整合各个像素的资料。因此在本次实验中决定采用CCD图像传感器。如图2-5所示:
6
图2-5 CCD图像传感器
2.4.2 A/D转换电路
本设计采用的A/D转换芯片是TVP5150芯片。此芯片采用四面32脚封装。TVP5150是超低功耗,支持NTSC/PAL/SECAM等高格式的高性能视频解码器,它正常工作时,功耗仅115MW。它可以接受两路CVBS或一路S-VIDEO信号,通过IIC总线设置其内部寄存器,可以输出8位4:2:2的ITUBT.656信号。
TVP51510芯片采用14.13818MHZ晶振作为输入时钟,数字和模拟量均为1.8V,IO口电压为3.3V;信号输入有IP1A和IP1B两路,并且都进行阻抗匹配设计,防止对输入量信号的反射;YOUT【0:7】输出8路YCbCr信号,行场同步信号选择引脚HSYNC和VSYNC输出;SCLK引脚向DM644芯片输出27MHZ时钟信号,用来同步采集。其电路如图2-6所示:
7
图2-6 A/D转换电路
2.5 图像显示电路
图像显示电路包括了D/A转换电路和VGA接口电路。
本实验采用的D/A转换芯片是ADV7123芯片。ADV7123是三路高速、10位输入的视频DA转换器,具有330MHz的最大采样速度,与多种高精度的显示系统兼容,包括RS2343A和RS2 170,可以广泛应用于如HDTV、数字视频系统(1600×1200@100Hz)、高分辨率的彩色图片图像处理、视频信号再现等,因此能够满足我们多方面应用需求。
VGA接口是一种D型接口,上面共有15针孔,分成三排,每排五个。 其中,除了2根NC(Not Connect)信号、3根显示数据总线和5个GND信号,比较重要的是3根RGB彩色分量信号和2根扫描同步信号HSYNC和VSYNC针。VGA接口中彩色分量采用RS343电平标准。 其总体电路如图2-7所示:
8
图2-7 D/A转换电路
9
3 图像采集系统的软件设计
3.1 系统的设计环境
本次实验采用的是Quartus II9.1软件提供的多平台设计环境。Altera公司的Quartus II软件提供了可编程片上系统设计的一个综合开发环境,是进行EDA设计的基础工具。Quartus II集成开发环境包括以下内容:系统级设计,嵌入式软件开发,可编程逻辑器件(PLD)设计,综合,布局和布线,验证和仿真。Quartus II设计软件根据设计者需要提供了一个完整的多平台开发环境,它包含整个FPGA和CPLD设计阶段的解决方案。与以往的EDA工具相比,它更适合于设计团队基于模块的层次化设计方法。Quartus II软件的典型设计流程一般可分为设计输入、设计实现和器件编程三个设计步骤及相应的功能仿真、时序仿真和器件测试三个设计验证过程:
设计输入:设计输入有多种方式,目前最常用的有电路图和硬件描述语言两种。对于简单的设计,可采用原理图或ABEL语言设计。对于复杂的设计,可使用原理图或硬件描述语言(如VHDL,Verilog语言等),或两者混用,采用层次化设计方法,分模块、分层次地进行描述。设计输入软件在设计输入时会检查语法错误,产生网表文件,供设计实现和设计校验用。
设计实现:设计实现是指从设计输入文件到位流文件的编译过程。在该过程中,编译软件自动地对设计文件进行综合、优化并针对所选中的器件进行映射、布局和布线,产生相应的位流数据文件。
器件编程:器件的编程也称为器件的配置,就是将位流数据文件配置到相应的FPGA器件中。FPGA器件的配置方式分为两大类;主动配置方式和被动配置方式。主动配置方式是由GAL器件引导配置操作过程,它控制着外部存储器和初始化过程;而被动配置是由外部机或控制器控制配置过程。
设计校验:对应于功能仿真、时序仿真、器件测试组成的设计验证过程。功能仿真验证设计的逻辑功能。在设计输入过程中,对部分功能或整个设计均可进行功能仿真。时序仿真是在设计实现后,针对器件的布局、布线方案进行的时延仿真,分析定时关系。器件测试是在器件编程后,通过实验或借助于测试工具,测试器件最终功能和性能指标。开发环境如图3-1所示:
10
图3-1 Quartus开发环境
3.2 设计的主要流程
本次实验其主要流程[7]如图3-2所示:
设计输入 CCD摄像头约束 综合 适配 时序分析 仿真 下载 图3-2 设计流程图
具体设计步骤:一是设计输入,可以原理图输入,也可以用VHDL 语言输入;输入完成后,就综合(其实综合就是编译,点击COMPILE 图标就可以了,软件会自动实现综合过
11
程);编译成功后,就开始时序仿真,通过创建输入信号波形(也就是激励文件),自动产生输出波形,看输出波形否和我们设计的一致,是否正确,正确的话,通过JTAG下载。
3.3 设计内部数据量的变换
根据视频图像采集系统软件设计的功能可以推测出本实验包括的主要模块有IIC_CONFIG 模块和TV_TO_VGA 模块。其中IIC_CONFIG 模块主要是用来通过给TVP5150赋值来控制 TVP5150工作模式 。TVP5150采用IIC 总线接口配置,采用Verilog HDL 硬件描述语言设计实现,集成了一个视频解码器,能够满足高达6 通道模拟视频输入,可以自动检测标准模拟基带电视信号,包括NTSC,PAL,SECAM 视频制式,转换为符合CCIR601/CCIR656 的4:2:2 分量数字视频数据。对TVP5150 的配置,只需将数据写入TVP5150 的寄存器中,所以IIC 控制器只需实现IIC 的写数据控制。整个功能由两个模块来完成,IIC_Controller 模块用来产生IIC 总线规范的时序,IIC_Config 模块用来产生需要配置的寄存器的地址和配置参数[5]。TV_TO_VGA 模块主要包括ITU_R656 解码模块、视频图像存储模块、YUV 到RGB 色域模块,完成的功能包含视频信号的采集、分配、存储以及色度空间的转换。ITU_R656 解码模块对电视解码器芯片TVP5150 解码得到的YCrCb(4:4:2) 数据源在插值之后得到YCrCb(4:4:4)信号,同时生成13.5MHz 的像素时钟及消隐信号。其中双端口线路缓冲器模块和HSYNC×2 模块可以实现去交织操作,时钟像素从13.5MHz 变为27MHz,HSYNC 信号从31.4kHz 降到15.7kHz。双端口吸纳路缓冲器模块内部使用一个1K 字节长的双口SRAM 将YCrCb 数据量加倍。最终YCrCb2RGB 模块将YCrCb×2 数据送到VGA 显示器上输出,VGA 时序发生器模块用来生成单独的VGA同步信号VGA_HS 和VGA_VS,以便VGA 显示器显示输出数据[8]。
3.3.1 IIC数据总线
IIC总线是用于连接微控制器及外围设备的。其主要特征有以下几点: (1):只要求两条总线线路:一条串行数据线SDA,一条串行时钟线SCL。 (2):每个连接到总线的器件都可以通过唯一的地址和一直存在的简单的主机/从机关系软件设定地址,主机可以作为主机发送器或主机接收器;
(3):它是一个真正的多主机总线,如果两个或更多主机同时初始化,数据传输可以通过冲突检测和仲裁防止数据被破坏;
(4):串行的8 位双向数据传输位速率在标准模式下可达100kbit/s,快速模式下可达400kbit/s,高速模式下可达3.4Mbit/s;
(5):连接到相同总线的IC 数量只受到总线的最大电容400pF 限制。
而实现实现IIC总线通信协议主要有两种方法:利用MCU对两根I/O口线进行软件编程,模拟IIC总线的SCL和SDA时序要求;使用专用IIC总线控制核,但受其主机接口方式和时钟频率的限制,在有些场合应用并不方便。本设计中用VHDL对FPGA的两根I/O口进行IIC总线控制核设计。
12
IIC控制模块的设计按照的是自顶而下的方法。其可分成三个模块: 12C_TOP模块、IIC_CMD模块、12C_CORE模块。其大致结构如图3-3所示:
IIC_TOP 模块 IIC_CMD 模块 IIC_CORE 模块 CCD 外部采集设备 图3-3 IIC模块内部设计
此图中IIC_TOP是顶层控制模块主要负责接受FPGA发来的控制信号、命令及数据;发送由从设备读出的数据和确认位到FPGA;实现IIC控制核与FPGA的中断通信机制;提供当前IIC的工作状态;把FPGA发出的命令信号IIC_cmd模块。IIC控制设计的核心工作是对IIC总线命令及时序的状态发送到划分。在控制核内设置了两个状态机,分别称为命令状态机和时序状态机,其中命令状态机用于管理IIC总线具体的读写操作的命令状态转移过程;时序状态机用于实现IIC总线上启动、停止、读、写、确认等命令的具体时序关系。
IIC的工作原理:IIC总线是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据。在CPU与被控IC之间、IC与IC之间进行双向传送,最高传送速率100kbps。各种被控制电路均并联在这条总线上,但就像电话机一样只有拨通各自的号码才能工作,所以每个电路和模块都有唯一的地址,在信息的传输过程中,IIC总线上并接的每一模块电路既是主控器(或被控器),又是发送器(或接收器),这取决于它所要完成的功能。CPU发出的控制信号分为地址码和控制量两部分,地址码用来选址,即接通需要控制的电路,确定控制的种类;控制量决定该调整的类别(如对比度、亮度等)及需要调整的量。这样,各控制电路虽然挂在同一条总线上,却彼此独立,互不相关。
IIC总线在传送数据过程中共有三种类型信号, 它们分别是:开始信号、结束信号和应答信号。
开始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。 结束信号:SCL为低电平时,SDA由低电平向高电平跳变,结束传送数据。 应答信号:接收数据的IC在接收到8bit数据后,向发送数据的IC发出特定的低电平
13
脉冲,表示已收到数据。CPU向受控单元发出一个信号后,等待受控单元发出一个应答信号,CPU接收到应答信号后,根据实际情况作出是否继续传递信号的判断。若未收到应答信号,由判断为受控单元出现故障。IIC时序模块的电平交换如图3-4所示:
图3-4 IIC时序模块的电平交换
目前有很多半导体集成电路上都集成了IIC接口。带有IIC接口的单片机有:CYGNAL的 C8051F0XX系列,PHILIPSP87LPC7XX系列,MICROCHIP的PIC16C6XX系列等。很多外围器件如存储器、监控芯片等也提供IIC接口。
3.3.2 数据扫描程序
水平线像素计数:
在计数过程中先给与一个信号,如果是下降沿信号则像素计数器清零,如果不是则检查是否为最后一行,如果是则像素计数器清零,不是的话开始计数。
always @ (posedge pixel_clock or negedge_reset_n) begin if (!reset_n) begin
创建水平同步脉冲:
14
// 寄存器清0
end
pixel_count <= 11'h000;
else if (pixel_count == (`H_TOTAL - 1))
begin end
pixel_count <= pixel_count +1;
begin end
// 最后一行 // 寄存器清0
end
pixel_count <= 11'h000;
else
always @ (posedge pixel_clock or negedge reset_n) begin
else if (pixel_count == (`H_TOTAL - `H_BACK_PORCH -1))
// 停止计数
hs <= 1'b0;
begin
end
else if (pixel_count == (`H_ACTIVE + `H_FRONT_PORCH -1)) begin
end
// 开始计数
hs <= 1'b1;
if (!reset_n)
begin end
hs <= 1'b0;
// 计数器清0
end
IICC总线初始化:
IIC模块的初始化包括以下几个方面: 1.从机初始化
(1)写:IICA——设置从地址。 (2)写:IICC——使能IIC和中断。
(3)初始化若干所需RAM变量用于数据传输。 2.主机初始化
(1)写:IICF——设置IIC波特率。 (2)写:IICC——使能IIC和中断。
(3)初始化若干所需的RAM变量用于数据传输。 (4)写:IICC——使能TX(这一位表征发送/接收)。 (5)写:IICC——使能MST(主模式)。
(6)写:IICD寻址从目标(这个字节的最低一位将确定这次通信是主接收还是主发送)。 IIC总线在图像采集系统中初始化过程[14]如图3-5所示:
15
开始 视频设备开启 获取设备信息和图像信息 初始化采集窗口、颜色模式、帧状态 捕捉视频数据 N 是否终止视频采集 Y 图像数据处理 关闭视频设备 结束
图3-5 IIC初始化过程图
16
4 调试
检查硬件电路,测试电路板能否正常工作。若硬件电路没有问题的话,即可给电路板加电进行测试,加载如见对软件进行测试。
通过实验板上FPGA 的对图像解码芯片TVP5150 芯片以及ADV7123 芯片进行初始化,图像数据由PAL 制式的CCD 摄像头提供,由图像解码芯片TVP5150 转换成数字图像后,采集到FPGA 中相应的处理过后再通过FPGA将数据发送给数模转换芯片ADV7123,由ADV7123 将数字信号转换成模拟视频信号,通过VGA 接口输出到CRT显示器上即可验证结果的正确与否。其结果如下:
图4-1 图像采集系统的调试结果
17
参考文献
[1] 刘焕军,王耀南,段 峰.机器视觉中的图像采集技术.电脑与信息技术.2003 年第1 期 [2] 陆绍强. FPGA 将逐渐取代ASIC 和ASSP.电子产品世界,2000.9 [3] 李玉山等.图像采集及边缘提取ASIC 设计.西安电子科技大学学报,1995 [4] 李广军,孟宪元.可编程ASIC 设计与应用.成都,电子科技大学出版社,2000 [5] 宋万杰,罗丰,吴顺君. CPLD 技术
[7] 褚振勇,翁木云. FPGA 设计与应用. 西安:西安点子科技大学出版社, 2002 [8] 姚天任,江太辉. 数字信号处理. 武汉: 华中理工大学出版社, 1987
[9] 姚天任,孙洪. 现代数字信号处理.武汉及其应用. 西安西安电子科技大学出版社, 1999 [10] 章毓晋.图像处理与分析.北京:清华大学出版社,1999
[11] 沈庭芝. 数字图像处理及模式识别.北京:北京理工大学出版社,1998 [12] 康华光. 电子技术基础模拟部分. 北京:高等教育出版社, 1979
[13] 沙吉乐,曲兴华,关红彦等.基于FPGA 技术的新型高速图像采集[J].集成电路应用,2000 [14] 刘焕军,王耀南,段峰.机器视觉的图像采集技术.电脑信息与技术,2003
18
附 录
IIC_controller.v
/ -------------------------------------------------------------------- // Copyright (c) 2005 by Terasic Technologies Inc.
// -------------------------------------------------------------------- //
// Permission: //
// Terasic grants permission to use and modify this code for use
// in synthesis for all Terasic Development Boards and Altrea Development // Kits made by Terasic. Other use of this code, including the selling // ,duplication, or modification of any portion is strictly prohibited. //
// Disclaimer: //
// This VHDL or Verilog source code is intended as a design reference // which illustrates how these types of functions can be implemented. // It is the user's responsibility to verify their design for // consistency and functionality through the use of formal
// verification methods. Terasic provides no warranty regarding the use // or functionality of this code. //
// -------------------------------------------------------------------- //
// Terasic Technologies Inc
// 356 Fu-Shin E. Rd Sec. 1. JhuBei City, // HsinChu County, Taiwan // 302 //
// web: http://www.terasic.com/ // email:*******************//
// -------------------------------------------------------------------- //
// Major Functions:IIC controller //
// --------------------------------------------------------------------
19
//
// Revision History :
// --------------------------------------------------------------------
// Ver :| Author :| Mod. Date :| Changes Made:
// V1.0 :| Joe Yang :| 05/07/10 :| Initial Revision // -------------------------------------------------------------------- `timescale 1ns/100ps module IIC_Controller ( CLOCK,
IIC_SCLK,//IIC CLOCK IIC_SDAT,//IIC DATA
IIC_DATA,//DATA:[SLAVE_ADDR,SUB_ADDR,DATA] GO, //GO transfor END, //END transfor W_R, //W_R ACK, //ACK RESET, //TEST
SD_COUNTER, SDO );
input CLOCK;
input [23:0]IIC_DATA; input GO;
input RESET; input W_R;
inout IIC_SDAT; output IIC_SCLK; output END; output ACK;
//TEST
output [5:0] SD_COUNTER; output SDO;
reg SDO; reg SCLK; reg END; reg [23:0]SD;
reg [7:0]SD_COUNTER; reg IIC_SCLK;
//wire IIC_SCLK=SCLK | ( ((SD_COUNTER >= 4) & (SD_COUNTER <=30))? ~CLOCK :0 ); wire IIC_SDAT=SDO?1'bz:0 ;
20
reg ACK1,ACK2,ACK3;
wire ACK=ACK1 | ACK2 |ACK3;
//--IIC COUNTER
always @(negedge RESET or posedge CLOCK ) begin if (!RESET) SD_COUNTER=8'b11111111; else begin if (GO==0)
SD_COUNTER=8'd0; else
if (SD_COUNTER < 8'b11111111) SD_COUNTER=SD_COUNTER+1; end end //----
always @(negedge RESET or posedge CLOCK ) begin
if (!RESET) begin IIC_SCLK=1;SDO=1; ACK1=0;ACK2=0;ACK3=0; END=1; end else
case (SD_COUNTER)
8'd0 : begin ACK1=1 ;ACK2=1 ;ACK3=1 ; END=0; SDO=1; IIC_SCLK=1;end //start
8'd1 : begin SD= #1 IIC_DATA;SDO= #1 1;end 8'd2 : begin SDO= #1 0; end //SLAVE ADDR
8'd3 : begin IIC_SCLK= #1 0; end 8'd4 : begin SDO= #1 SD[23]; end 8'd5 : begin IIC_SCLK= #1 1; end 8'd6 : begin IIC_SCLK= #1 0; end 8'd7 : SDO= #1 SD[22];
8'd8 : begin IIC_SCLK= #1 1; end 8'd9 : begin IIC_SCLK= #1 0; end 8'd10 : SDO= #1 SD[21];
8'd11 : begin IIC_SCLK= #1 1; end 8'd12 : begin IIC_SCLK= #1 0; end 8'd13 : SDO= #1 SD[20];
8'd14 : begin IIC_SCLK= #1 1; end 8'd15 : begin IIC_SCLK= #1 0; end 8'd16 : SDO= #1 SD[19];
8'd17 : begin IIC_SCLK= #1 1; end 8'd18 : begin IIC_SCLK= #1 0; end 8'd19 : SDO= #1 SD[18];
8'd20 : begin IIC_SCLK= #1 1; end 8'd21 : begin IIC_SCLK= #1 0; end
21
8'd22 : SDO= #1 SD[17];
8'd23 : begin IIC_SCLK= #1 1; end 8'd24 : begin IIC_SCLK= #1 0; end 8'd25 : SDO= #1 SD[16];
8'd26 : begin IIC_SCLK= #1 1; end 8'd27 : begin IIC_SCLK= #1 0; end 8'd28 : begin SDO= #1 1'b1;end
8'd29 : ACK1= #1 IIC_SDAT; //ACK 8'd30 : begin IIC_SCLK= #1 1; end 8'd31 : begin IIC_SCLK= #1 0; end //SUB ADDR
8'd32 : begin SDO= #1 SD[15]; end 8'd33 : begin IIC_SCLK= #1 1; end 8'd34 : begin IIC_SCLK= #1 0; end 8'd35 : SDO= #1 SD[14];
8'd36 : begin IIC_SCLK= #1 1; end 8'd37 : begin IIC_SCLK= #1 0; end 8'd38 : SDO= #1 SD[13];
8'd39 : begin IIC_SCLK= #1 1; end 8'd40 : begin IIC_SCLK= #1 0; end 8'd41 : SDO= #1 SD[12];
8'd42 : begin IIC_SCLK= #1 1; end 8'd43 : begin IIC_SCLK= #1 0; end 8'd44 : SDO= #1 SD[11];
8'd45 : begin IIC_SCLK= #1 1; end 8'd46 : begin IIC_SCLK= #1 0; end 8'd47 : SDO= #1 SD[10];
8'd48 : begin IIC_SCLK= #1 1; end 8'd49 : begin IIC_SCLK= #1 0; end 8'd50 : SDO= #1 SD[9];
8'd51 : begin IIC_SCLK= #1 1; end 8'd52 : begin IIC_SCLK= #1 0; end 8'd53 : SDO= #1 SD[8];
8'd54 : begin IIC_SCLK= #1 1; end 8'd55 : begin IIC_SCLK= #1 0; end 8'd56 : begin SDO= #1 1'b1;end
8'd57: begin ACK2= #1 IIC_SDAT;end//ACK 8'd58 : begin IIC_SCLK= #1 1; end 8'd59 : begin IIC_SCLK= #1 0; end //DATA
8'd60 : begin SDO= #1 SD[7]; end 8'd61 : begin IIC_SCLK= #1 1; end 8'd62 : begin IIC_SCLK= #1 0; end 8'd63 : SDO= #1 SD[6];
22
8'd64 : begin IIC_SCLK= #1 1; end 8'd65 : begin IIC_SCLK= #1 0; end 8'd66 : SDO= #1 SD[5];
8'd67 : begin IIC_SCLK= #1 1; end 8'd68 : begin IIC_SCLK= #1 0; end 8'd69 : SDO= #1 SD[4];
8'd70 : begin IIC_SCLK= #1 1; end 8'd71 : begin IIC_SCLK= #1 0; end 8'd72 : SDO= #1 SD[3];
8'd73 : begin IIC_SCLK= #1 1; end 8'd74 : begin IIC_SCLK= #1 0; end 8'd75 : SDO= #1 SD[2];
8'd76 : begin IIC_SCLK= #1 1; end 8'd77 : begin IIC_SCLK= #1 0; end 8'd78 : SDO= #1 SD[1];
8'd79 : begin IIC_SCLK= #1 1; end 8'd80 : begin IIC_SCLK= #1 0; end 8'd81 : SDO= #1 SD[0];
8'd82 : begin IIC_SCLK= #1 1; end 8'd83 : begin IIC_SCLK= #1 0; end 8'd84 : begin SDO= #1 1'b1; end
8'd85: begin ACK3= #1 IIC_SDAT; end//ACK 8'd86 : begin IIC_SCLK= #1 1; end 8'd87 : begin IIC_SCLK= #1 0; end
//stop
8'd88 : begin SDO= #1 1'b0; end 8'd89: begin IIC_SCLK= #1 1'b1; end 8'd90 : begin SDO= #1 1'b1; END= #1 1; end
default:begin SDO= #1 1'b1; IIC_SCLK= #1 1'b1; end endcase end
endmodule
23
VGA.v
include \"svga_defines.v\" module VGA (
input reset_n, input pixel_clock,
output reg hs, output reg vs, output reg blank, output reg DE,
output reg [23:0] rgb );
reg [10:0] pixel_count; reg [10:0] line_count; reg h_blank; reg v_blank; reg DE_d;
// CREATE THE HORIZONTAL LINE PIXEL COUNTER always @ (posedge pixel_clock or negedge reset_n) begin if (!reset_n) begin // on reset_n set pixel counter to 0 pixel_count <= 11'h000; end
else if (pixel_count == (`H_TOTAL - 1)) begin // last pixel in the line pixel_count <= 11'h000; // reset_n pixel counter end else begin pixel_count <= pixel_count +1; end end
// CREATE THE HORIZONTAL SYNCH PULSE
always @ (posedge pixel_clock or negedge reset_n) begin
24
if (!reset_n) begin // on reset_n hs <= 1'b0; // remove h_synch end
else if (pixel_count == (`H_ACTIVE + `H_FRONT_PORCH -1)) begin // start of h_synch hs <= 1'b1; end
else if (pixel_count == (`H_TOTAL - `H_BACK_PORCH -1)) begin // end of h_synch hs <= 1'b0; end end
// CREATE THE VERTICAL FRAME LINE COUNTER always @ (posedge pixel_clock or negedge reset_n) begin if (!reset_n) begin // on reset_n set line counter to 0 line_count <= 10'h000; end
else if ((line_count == (`V_TOTAL - 1))&& (pixel_count == (`H_TOTAL - 1))) begin // last pixel in last line of frame line_count <= 10'h000; // reset_n line counter end
else if ((pixel_count == (`H_TOTAL - 1))) begin // last pixel but not last line line_count <= line_count + 1;// increment line counter end end
// CREATE THE VERTICAL SYNCH PULSE
always @ (posedge pixel_clock or negedge reset_n) begin if (!reset_n) begin // on reset_n vs = 1'b0; // remove v_synch end
else if ((line_count == (`V_ACTIVE + `V_FRONT_PORCH -1) && (pixel_count == `H_TOTAL - 1)))
25
begin // start of v_synch vs = 1'b1; end
else if ((line_count == (`V_TOTAL - `V_BACK_PORCH - 1)) && (pixel_count == (`H_TOTAL - 1))) begin // end of v_synch vs = 1'b0; end end
// CREATE THE VERTICAL BLANKING SIGNAL always @ (posedge pixel_clock or negedge reset_n) begin if (!reset_n) begin // on reset DE <= 1'b0; // DE_d <= 1'b0; end else
begin // DE_d <= !blank; DE <= DE_d; end end
always @ (posedge pixel_clock or negedge reset_n) begin if (!reset_n) begin // on reset h_blank <= 1'b0; // remove the h_blank end
else if (pixel_count == (`H_ACTIVE -2)) begin // start of HBI h_blank <= 1'b1; end
else if (pixel_count == (`H_TOTAL -2)) begin // end of HBI h_blank <= 1'b0; end end
// CREATE THE VERTICAL BLANKING SIGNAL
26
// the \"-2\" is used instead of \"-1\" in the horizontal factor because of the extra // register delay for the composite blanking signal
always @ (posedge pixel_clock or negedge reset_n) begin if (!reset_n) begin // on reset v_blank <= 1'b0; // remove v_blank end
else if ((line_count == (`V_ACTIVE - 1) && (pixel_count == `H_TOTAL - 2))) begin // start of VBI v_blank <= 1'b1; end
else if ((line_count == (`V_TOTAL - 1)) && (pixel_count == (`H_TOTAL - 2))) begin // end of VBI v_blank <= 1'b0; end end
// CREATE THE COMPOSITE BANKING SIGNAL always @ (posedge pixel_clock or negedge reset_n) begin if (!reset_n) begin // on reset blank <= 1'b0; // remove blank end
else if (h_blank || v_blank) // blank during HBI or VBI begin blank <= 1'b1; end else begin blank <= 1'b0; // active video do not blank end end
// CREATE THE COLOUR BAR SIGNAL /*
always @(posedge pixel_clock or negedge reset_n) begin if(!reset_n) begin rgb <= 24'b0; end
27
// // // // // // // // else if(line_count == 1) begin rgb <= 24'hff00ff; end
else if(pixel_count == 0) begin rgb <= 24'hffffff; end
else if(pixel_count <= 159) begin rgb <= 24'b0; end
else if(pixel_count > 159 && pixel_count <= 319) begin rgb <= 24'hffffff; end
else if(pixel_count > 319 && pixel_count <= 479) begin rgb <= 24'hff0000; end
else if(pixel_count > 479 && pixel_count <= 639) begin rgb <= 24'h00ff00; end
else if(pixel_count > 639 && pixel_count <= 799) begin rgb <= 24'h0000ff; end
else if(pixel_count > 799&& pixel_count <= 959) begin rgb <= 24'hffff00; end
else if(pixel_count > 959 && pixel_count <= 1119) begin rgb <= 24'h00ffff; end
else if(pixel_count > 1119 && pixel_count <= 1279) begin rgb <= 24'hff00ff; end else begin rgb <= 24'b0; end
28
end */
always @(posedge pixel_clock or negedge reset_n) begin if(!reset_n) begin rgb <= 24'b0; end else begin rgb <= {pixel_count[10:3],8'b0,pixel_count[10:3]}; end // else // begin // rgb <= 24'b0; // end end
endmodule
29
30
因篇幅问题不能全部显示,请点此查看更多更全内容