版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
基于FPGA的運(yùn)動(dòng)目標(biāo)識(shí)別系統(tǒng)設(shè)計(jì)系統(tǒng)硬件設(shè)計(jì) 基于FPGA的運(yùn)動(dòng)目標(biāo)識(shí)別系統(tǒng)總體結(jié)構(gòu)VGA顯示器SDRAM芯片圖像處理模塊攝像頭采集模塊圖像傳感器VGA顯示器SDRAM芯片圖像處理模塊攝像頭采集模塊圖像傳感器OV7670圖像傳感器初始化配置模塊OV7670圖像傳感器初始化配置模塊VGA控制模塊SDRAM控制模塊VGA控制模塊SDRAM控制模塊FPGAFPGA基于FPGA的運(yùn)動(dòng)目標(biāo)識(shí)別系統(tǒng)主要包括以下幾個(gè)模塊:OV7670圖像傳感器初始化配置模塊、攝像頭數(shù)據(jù)采集模塊、基于SDRAM視頻處理顯示模塊等。整個(gè)系統(tǒng)流程如下:首先,在FPGA中OV7670圖像傳感器初始化配置模塊對(duì)圖像傳感器OV7670中寄存器進(jìn)行數(shù)據(jù)寫(xiě)入,攝像頭可以按照數(shù)字輸出數(shù)據(jù)流的要求輸出,F(xiàn)PGA中數(shù)據(jù)采集模塊再采集數(shù)據(jù)流,然后通過(guò)視頻數(shù)據(jù)格式轉(zhuǎn)換和目標(biāo)識(shí)別模塊即圖像處理模塊,再在SDRAM中緩存,最后再送到VGA顯示器顯示。FPGA開(kāi)發(fā)板阿爾特拉公司的“颶風(fēng)”四代系列FPGA器件繼承了Cyclone系列產(chǎn)品成本低廉、功耗小的優(yōu)良傳統(tǒng),本平臺(tái)所用的是其中的颶風(fēng)四代E系列器件,其優(yōu)點(diǎn)是以最低的功耗,通過(guò)最低的成本實(shí)現(xiàn)較高的功能性,其資源包括66個(gè)18*18的乘法器,是可以實(shí)現(xiàn)DSP處理密集型應(yīng)用,嵌入式存儲(chǔ)器有594Kbits,邏輯單元有22320LE,還支持包括串行數(shù)字接口的多種協(xié)議。 開(kāi)發(fā)板電路包括FPGA的電源模塊、FPGA的配置模塊(即JTAG和ASP等)、時(shí)鐘電路及復(fù)位模塊和SDRAM模塊。開(kāi)發(fā)板實(shí)物圖 OV7670攝像頭接收640*480像素,每秒30fps的數(shù)據(jù)。VGA顯示640*480分辨率高達(dá)60fps,每秒共30M帶寬的圖像。這點(diǎn)處理要求理論上對(duì)于FPGA來(lái)說(shuō)綽綽有余,但這要求放至任意一塊常見(jiàn)的MCU,甚至是ARM核,都是有點(diǎn)難以想象的。實(shí)現(xiàn)單片機(jī)做不到的事情,才是FPGA的優(yōu)勢(shì)所在。圖像傳感器圖像傳感器,是組成數(shù)字?jǐn)z像頭的重要組成部分。根據(jù)元件的不同,可分為CCD(ChargeCoupledDevice,電荷耦合元件)和CMOS(ComplementaryMetal-OxideSemiconductor,金屬氧化物半導(dǎo)體元件)兩大類。CCD提供的圖像質(zhì)量可以非常好,抗噪能力高和設(shè)計(jì)靈活。雖然由于增加了外圍電路使系統(tǒng)的尺寸變大,復(fù)雜性變高,但提高了電路設(shè)計(jì)的靈活性,可以隨設(shè)計(jì)者要求特意提高某方面性能。CCD更適合于注重性能而不太注重成本的應(yīng)用領(lǐng)域,如天文,醫(yī)療X光影像和對(duì)圖像的噪聲要求高的應(yīng)用領(lǐng)域。CMOS是使用了現(xiàn)代大規(guī)模半導(dǎo)體集成電路生產(chǎn)工藝來(lái)生產(chǎn)出的圖像傳感器,因技術(shù)成熟,有成品率高、集成度高和成本低等特點(diǎn)。CMOS技術(shù)早就成為圖像傳感器企業(yè)關(guān)注的重點(diǎn),希望可以兼有CCD圖像傳感器的特點(diǎn)。經(jīng)過(guò)不懈的嘗試,CMOS圖像傳感器可以兼有CCD圖像傳感器的優(yōu)點(diǎn)了,甚至可以與之媲美,使CMOS圖像傳感器成為主流產(chǎn)品。CMOS的工藝特點(diǎn)使它們更適用于要求體積小和功耗低而不需要圖像噪聲和質(zhì)量特別高的場(chǎng)合。像大多數(shù)安全防護(hù)應(yīng)用和大多數(shù)消費(fèi)型數(shù)碼產(chǎn)品應(yīng)用。本課題使用的攝像頭是來(lái)自是OvmniVision公司的攝像頭,型號(hào)是OV7670,屬于CMOS攝像頭,支持I2C接口,自帶的AD轉(zhuǎn)換精度為10位,VGA圖像最高達(dá)到30幀每秒,像素面積為3.6um*3.6um,是逐行掃描模式,像素是30W,支持自動(dòng)曝光控制、自動(dòng)增益控制、自動(dòng)白平衡、自動(dòng)消除燈光條紋、圖像縮放,工作模式下的工號(hào)為60mw,輸出格式支持RawRGB(將每一個(gè)像素的數(shù)據(jù)直接輸出)、RGB565\555\444(三原色紅綠藍(lán)模式,后面數(shù)字分別代表紅綠藍(lán)的位數(shù))、YUV\YCbCr4:2:2(亮度信號(hào)Y和兩個(gè)色差信號(hào)B-Y(即U)、R-Y(即V),數(shù)字代表數(shù)據(jù)為Y-U-Y-V次序輸出的),輸出數(shù)據(jù)都為8位D{7...0},其它輸出的數(shù)據(jù)還包括CMOS_HREF(行同步信號(hào)),CMOS_VSYNC(場(chǎng)同步信號(hào)),CMOS_PCLK(輸出像素時(shí)鐘信號(hào)),當(dāng)然還有對(duì)OV7670配置的I2C相關(guān)引腳CMOS_SCLK和CMOS_SDATA。攝像頭里的功能模塊包括有感光陣列、模擬信號(hào)處理、AD轉(zhuǎn)換、測(cè)試圖案發(fā)生器、數(shù)字信號(hào)處理器、圖像縮放、時(shí)序發(fā)生器、數(shù)字視頻端口、SCCB接口(即I2C接口)、LED和閃光燈輸出控制。由此可見(jiàn),有很大一部分?jǐn)?shù)據(jù)轉(zhuǎn)換都在內(nèi)部處理完成了。VGA顯示接口VGA接口是一種D型接口,上面共有15針,分成三排,每排五個(gè),VGA接口針腳定義如圖2-3所示。接口有2根NC(NotConnect)信號(hào)針,3根顯示數(shù)據(jù)總線針,5個(gè)GND信號(hào)針,另外比較重要的是3根RGB彩色分量信號(hào)和2根掃描同步信號(hào)HSYNC和VSYNC針。VGA接口中彩色分量采用RS343電平標(biāo)準(zhǔn)。RS343電平標(biāo)準(zhǔn)的峰值電壓為1V。VGA接口是顯卡上應(yīng)用最為廣泛的接口類型,多數(shù)的顯卡都帶有此種接口。本系統(tǒng)使用了一個(gè)外設(shè)VGA接口,自帶一個(gè)DAC轉(zhuǎn)換芯片,可以直接將輸出的數(shù)字信號(hào)轉(zhuǎn)換為VGA能接受的零到七伏特電平,輸出給顯示器顯示圖像。第三章運(yùn)動(dòng)目標(biāo)識(shí)別系統(tǒng)模塊化設(shè)計(jì)運(yùn)動(dòng)目標(biāo)識(shí)別系統(tǒng)頂層設(shè)計(jì)圖3-1運(yùn)動(dòng)目標(biāo)識(shí)別系統(tǒng)頂層結(jié)構(gòu)圖整個(gè)系統(tǒng)軟件設(shè)計(jì)主要為以上幾個(gè)模塊:時(shí)鐘及復(fù)位模塊、 OV7670圖像傳感器初始化配置模塊、攝像頭數(shù)據(jù)采集模塊和基于SDRAM的視頻處理顯示模塊。其中基于SDRAM的視頻處理顯示模塊又包括SDRAM緩存模塊,VGA驅(qū)動(dòng)程序模塊、視頻數(shù)據(jù)格式轉(zhuǎn)換程序和目標(biāo)識(shí)別模塊即圖像處理模塊。時(shí)鐘及復(fù)位模塊主要是為整個(gè)系統(tǒng)提供時(shí)鐘和復(fù)位信號(hào)。OV7670圖像傳感器初始化配置模塊是對(duì)圖像傳感器寄存器進(jìn)行初始化配置。攝像頭數(shù)據(jù)采集模塊是將攝像頭的傳入的初始數(shù)據(jù)采集并整合。SDRAM緩存模塊是控制SDRAM實(shí)現(xiàn)對(duì)數(shù)據(jù)緩存,為實(shí)時(shí)顯示提供可能。VGA驅(qū)動(dòng)程序是控制驅(qū)動(dòng)VGA顯示器正常顯示。視頻數(shù)據(jù)格式轉(zhuǎn)換程序是將視頻數(shù)據(jù)RGB565格式轉(zhuǎn)換為灰度圖像以便后續(xù)處理。目標(biāo)識(shí)別模塊是實(shí)現(xiàn)運(yùn)動(dòng)目標(biāo)識(shí)別,對(duì)相鄰幀的像素之和后相減,大于閾值即判斷有運(yùn)動(dòng)目標(biāo)。整個(gè)的工作過(guò)程為:先通過(guò)FPGA中I2C總線模塊對(duì)圖像傳感器OV7670中的寄存器進(jìn)行配置即數(shù)據(jù)寫(xiě)入,攝像頭才能按照要求輸出數(shù)字?jǐn)?shù)據(jù)流,在FPGA中采集數(shù)據(jù)模塊的數(shù)據(jù)流,然后發(fā)送到圖像處理模塊進(jìn)行處理,在SDRAM緩存,然后發(fā)送到VGA顯示。時(shí)鐘及復(fù)位模塊 開(kāi)發(fā)板自帶晶振振蕩器為25MHz,由PLL鎖相環(huán)分頻或倍頻出適合的頻率提供給各模塊 CLK是開(kāi)發(fā)板自帶的晶振時(shí)鐘輸入引腳。rst_n是復(fù)位引腳。sys_rst_n是接到各模塊的異步復(fù)位引腳。但是有一些模塊對(duì)這個(gè)時(shí)鐘頻率要求分頻或倍頻,所以要經(jīng)過(guò)時(shí)鐘模塊進(jìn)行分頻或倍頻。此外系統(tǒng)還需要一個(gè)復(fù)位設(shè)置,將這兩個(gè)功能整合在一個(gè)模塊中。在quartusII中直接調(diào)用PLL(鎖相環(huán)(PhaseLockedLoop))來(lái)完成我們的時(shí)鐘分頻或倍頻。PLL時(shí)鐘設(shè)置界面由圖可知從c0,c1和c2與自帶晶振的相對(duì)頻率、相位。c0為全局時(shí)鐘。c1是乒乓模塊和存儲(chǔ)控制模塊的時(shí)鐘信號(hào)。c2直接接到SDRAM中作為時(shí)鐘信號(hào)。攝像頭數(shù)據(jù)采集模塊 攝像頭采集的像素時(shí)鐘信號(hào)CMOS_PCLK,場(chǎng)同步信號(hào)CMOS_VSYNC,行同步信號(hào)CMOS_HREF和8位像素?cái)?shù)據(jù)CMOS_iDATA[7:0]去通過(guò)這個(gè)模塊采集,再送入下個(gè)顯示處理模塊。Init_Done接受來(lái)自I2C總線模塊的config_done信號(hào),高電平有效表示I2C初始化完成。CMOS_oclk是數(shù)據(jù)同步輸出時(shí)鐘。CMOS_VALID是數(shù)據(jù)輸出有效位。CMOS_XCLK等于全局時(shí)鐘。 要想對(duì)輸入數(shù)據(jù)進(jìn)行處理,就要首先知道進(jìn)來(lái)的數(shù)據(jù)是怎么樣的。所以通過(guò)quartusII平臺(tái)上的SignalTapII仿真得到攝像頭進(jìn)來(lái)的cmos_pclk像素時(shí)鐘信號(hào)、cmos_vsync場(chǎng)信號(hào)、cmos_href行信號(hào)和8位cmos_data像素?cái)?shù)據(jù)信號(hào)的時(shí)序圖。由圖可以看出,在場(chǎng)信號(hào)(默認(rèn)低有效),和行信號(hào)有效的同時(shí),攝像頭開(kāi)始輸出8位數(shù)據(jù)。因此就在此時(shí)要開(kāi)始拼接數(shù)據(jù):先保存第一個(gè)8位數(shù)據(jù),拼接到第二8位個(gè)數(shù)據(jù),實(shí)現(xiàn)一個(gè)完整16位像素?cái)?shù)據(jù)的輸出。然后要實(shí)現(xiàn)這16位數(shù)據(jù)在SDRAM的緩存,在拼接完成的同時(shí),給一個(gè)信號(hào)給FIFO使能,場(chǎng)同步信號(hào)作為SDRAM的地址清零信號(hào),這樣就能緩存這16位數(shù)據(jù)了。值得注意的是在此模塊中因?yàn)樵贠V攝像頭手冊(cè)中提到,前300ms數(shù)據(jù)會(huì)不穩(wěn)定,所以在本模塊設(shè)計(jì)中還特意丟棄了前10幀。OV7670圖像傳感器初始化配置模塊 I2C總線是用來(lái)初始化的OV7670圖像傳感器的設(shè)置,分辨率和PCLK像素時(shí)鐘設(shè)置和傳感器的輸出數(shù)據(jù)格式等等也可以這樣設(shè)置。I2C總線概況 I2C(InterIntegratedCircuit,內(nèi)部集成電路)總線是在上世紀(jì)80年代由PHILIPS公司為音視頻設(shè)備發(fā)明的兩線式串行總線,用于連接微控制器和外圍設(shè)備雖然總線沒(méi)有并行總線的吞吐率,效率明顯不足,但是因其只有兩條雙向信號(hào)線,分別為SCLKS和SDATA信號(hào)線,接口直接接在組件之上,硬件結(jié)構(gòu)十分簡(jiǎn)單,這兩條雙向信號(hào)線通過(guò)上拉電阻接到正電源電壓,初始狀態(tài)下兩線均為高電平,連接到總線的設(shè)備都有唯一的地址來(lái)發(fā)送或接收數(shù)據(jù),這個(gè)地址一般是設(shè)備出廠時(shí)就分配好的,也可以通過(guò)軟件設(shè)定。[7]原本OV攝像頭使用的是它自己公司的SerialCameraControlBus(SCCB)總線,然而與I2C總線的時(shí)序并沒(méi)有差別,所以下面就都介紹I2C總線了。I2C總線控制程序設(shè)計(jì) I2C總線控制程序設(shè)計(jì)原理圖如下首先介紹各引腳功能定義。管腳GO是傳送數(shù)據(jù)開(kāi)始標(biāo)志位,管腳I2C_CLK就是為I2C總線提供的數(shù)據(jù)傳輸?shù)墓ぷ鲿r(shí)鐘,管腳I2C_SCLK就是加在兩條總線上其中的SCLK時(shí)鐘信號(hào)線,管腳I2C_SDAT是加在兩條總線上其中的SDAT數(shù)據(jù)信號(hào)線,管腳iCLK是全局時(shí)鐘,管腳iRST_N是復(fù)位引腳,管腳I2C_WDATA[23..0]是主端口發(fā)送給從端口的配置數(shù)據(jù),包括7位從端口設(shè)備地址、1位數(shù)據(jù)方向、8位寄存器地址和要8位寫(xiě)入寄存器的設(shè)定數(shù)據(jù),管腳ACK為應(yīng)答位,管腳END是傳送數(shù)據(jù)結(jié)束標(biāo)志位,I2C_RDATA為讀取數(shù)據(jù)這里不作介紹。接下來(lái)介紹I2C總線傳輸過(guò)程為:主端口發(fā)送1位起始位,緊跟主端口發(fā)送的是從端口設(shè)備的8位地址即出廠分配的地址或可通過(guò)軟件設(shè)定,地址的最后一位表示該請(qǐng)求是寫(xiě)入還是讀取,為“0”表示請(qǐng)求寫(xiě)入,為“1”表示請(qǐng)求讀取,在從端口設(shè)備核對(duì)地址無(wú)誤后,向主端口發(fā)送一位應(yīng)答信號(hào)。圖大概介紹一下幾個(gè)重要過(guò)程:開(kāi)始條件:當(dāng)SCL為高電平期時(shí),SDA由高電平到低電平的跳變,即下降沿。 結(jié)束條件:當(dāng)SCL為高電平期時(shí),SDA由低電平到高電平的跳變,即上升沿。 開(kāi)始和結(jié)束信號(hào)都是由主機(jī)發(fā)出的,在開(kāi)始信號(hào)產(chǎn)生后,總線就是被占用的狀態(tài);在結(jié)束信號(hào)產(chǎn)生后,總線就是空閑狀態(tài)。 應(yīng)答位:主器件每發(fā)送一個(gè)字節(jié)后,即第九個(gè)時(shí)鐘脈沖時(shí),從器件釋放SDA數(shù)據(jù)線為表示應(yīng)答。 非應(yīng)答位:主器件每發(fā)送一個(gè)字節(jié)后,即第九個(gè)時(shí)鐘脈沖時(shí),從器件保持SDA數(shù)據(jù)線表示非應(yīng)答。從端口設(shè)備地址:8位地址,由7位地址和1位數(shù)據(jù)傳輸方向位組成。最低位為“0”表寫(xiě)入模式,為“1”表示讀取模式。寫(xiě)入過(guò)程:從端口設(shè)備地址:8位地址,由7位地址和1位數(shù)據(jù)傳輸方向位組成。最低位為"0”表寫(xiě)入模式,為"1”表示讀取模式。寫(xiě)入過(guò)程:(1)發(fā)送從器件的地址和讀寫(xiě)選擇位,等到從器件拉低SCL進(jìn)行應(yīng)答;如果從器件接收成功,則進(jìn)行應(yīng)答;如果握手不成功或從設(shè)備發(fā)送到錯(cuò)誤的數(shù)據(jù)不產(chǎn)生響應(yīng),則請(qǐng)求重發(fā)或終止。(2)發(fā)送想要寫(xiě)入的寄存器地址;從器件對(duì)其發(fā)出應(yīng)答;(3)發(fā)送數(shù)據(jù)。(4)發(fā)送停止位。然后介紹該程序設(shè)計(jì)的思路結(jié)構(gòu)流程圖如下:起始起始SCLK和SDAT保持高電平SCLK和SDAT保持高電平否開(kāi)始條件(SCLK保持高電平和SDAT下降沿)否開(kāi)始條件(SCLK保持高電平和SDAT下降沿)開(kāi)始條件(SCLK開(kāi)始條件(SCLK高電平和SDAT下降沿)是寫(xiě)入從設(shè)備地址是寫(xiě)入從設(shè)備地址否是否應(yīng)答否是否應(yīng)答是是否是否應(yīng)答寫(xiě)入寄存器地址否是否應(yīng)答寫(xiě)入寄存器地址是是寫(xiě)入配置數(shù)據(jù)寫(xiě)入配置數(shù)據(jù)否是否應(yīng)答否是否應(yīng)答是配置的寄存器數(shù)是否超過(guò)閾值否是配置的寄存器數(shù)是否超過(guò)閾值否是是結(jié)束結(jié)束全程序的大概思路是以全局時(shí)鐘為頻率,設(shè)置了SD_COUNTER計(jì)數(shù)器,以此為基礎(chǔ)把寫(xiě)入操作分為部分:空閑、起始、寫(xiě)入和終止。計(jì)數(shù)器為0時(shí)為空閑部分,空閑部分時(shí),SCLK和SDAT都為高電平,ACK1、ACK2和ACK3都為高電平。計(jì)數(shù)器為1到3時(shí),為起始部分,計(jì)數(shù)器為2時(shí),使SDAT為低電平,計(jì)數(shù)器為3時(shí),使SCLK 為低電平,這樣就滿足了寫(xiě)入過(guò)程的開(kāi)始條件。 計(jì)數(shù)器4到14,為寫(xiě)入從設(shè)備地址部分,4到11時(shí),從高位開(kāi)始,把7位從設(shè)備地址和1位讀寫(xiě)設(shè)置位,一位一位寫(xiě)入到SDAT。12到14時(shí),從SDAT讀取 ACK1,表示從設(shè)備地址寫(xiě)入完成。讀到的ACK1如果不是高阻態(tài),則計(jì)數(shù)器從0開(kāi)始重新計(jì)數(shù)。 計(jì)數(shù)器15到25,為寫(xiě)入寄存器地址,15到22時(shí),從高位開(kāi)始,把8位寄存器地址,一位一位寫(xiě)入到SDAT。23到25時(shí),,從SDAT上讀取ACK2,表示寄存器地址寫(xiě)入完成。如果讀到的ACK2不是高阻態(tài),則計(jì)數(shù)器從0開(kāi)始重新計(jì)數(shù)。 計(jì)數(shù)器26到36,為寫(xiě)入要配置的數(shù)據(jù)部分,26到33時(shí),從高位開(kāi)始,把8位數(shù)據(jù)寫(xiě)入,從高位開(kāi)始,一位一位寫(xiě)入到SDAT。34到36時(shí),從SDAT讀取ACK3,表示配置數(shù)據(jù)寫(xiě)入完成。讀到的ACK3如果不是高阻態(tài),則計(jì)數(shù)器從0開(kāi)始重新計(jì)數(shù)。 至此24位數(shù)據(jù)寫(xiě)入完成,傳輸成功。以上的子程序完成了對(duì)SCLK和SDAT信號(hào)線的具體分配,然而對(duì)各個(gè)信號(hào)的判斷和子程序的例化,需要在2級(jí)頂層程序里完成。 在2級(jí)頂層程序里,用的時(shí)鐘頻率有FPGA開(kāi)發(fā)板的25MHz自帶頻率,在程序中分頻為10KHz。在這個(gè)程序里設(shè)置了一個(gè)狀態(tài)機(jī),有三個(gè)狀態(tài),分別為“0、1和2”。0代表空閑狀態(tài),先判斷當(dāng)前寫(xiě)入的寄存器數(shù)是否超過(guò)了圖像傳感器的寄存器數(shù)的閾值,這里設(shè)置的閾值LUT_SIZE為168,數(shù)值由圖像傳感器決定。如果沒(méi)超過(guò)閾值的話再由END信號(hào)線判斷是否進(jìn)入1狀態(tài)即寫(xiě)入狀態(tài),表示開(kāi)始寫(xiě)入操作,如果24位數(shù)據(jù)都寫(xiě)入完成的話,即ACK1、2、3都為高阻態(tài),則進(jìn)入2狀態(tài)即寄存器地址加1,再轉(zhuǎn)到0狀態(tài)空閑狀態(tài)。I2C總線對(duì)OV7670寄存器的配置 本系統(tǒng)的開(kāi)發(fā)板作為主端口設(shè)備通過(guò)I2C總線來(lái)配置OV7670的寄存器,從端口設(shè)備只有OV7670圖像傳感器,雖然I2C總線協(xié)議與其他總線協(xié)議相對(duì)沒(méi)有那么復(fù)雜,但還是有一定的難度的,所以在本課題中只需要完成寫(xiě)入操作,無(wú)需讀取操作。 因本課題只有對(duì)圖像傳感器的寫(xiě)入操作,主端口先發(fā)送位設(shè)備地址Ox42(7位地址和1位數(shù)據(jù)方向,為設(shè)備出廠默認(rèn)設(shè)置),然后發(fā)送8位寄存器地址和8位配置數(shù)據(jù),每發(fā)送一個(gè)字節(jié),從端口收到后給出應(yīng)答信號(hào)ACK1、ACK2和ACK3。最后主端口發(fā)送結(jié)束標(biāo)志位,停止寫(xiě)操作。I2C總線寫(xiě)入時(shí)序圖 I2C總線8位寫(xiě)入操作時(shí)序如圖3-9所示。開(kāi)始時(shí),主端口首先發(fā)送1位開(kāi)始標(biāo)志位,即I2C_sclk保持高電平,I2C_sdat線下降沿。首先主端口在I2C_sdat數(shù)據(jù)線上發(fā)送從端口設(shè)備地址Ox42二進(jìn)制表示為(01000010),最后一位是“0”,代表寫(xiě)入操作,從高位到低位一位一位發(fā)送,發(fā)完8位之后,讀取到ACK1為三態(tài)(三態(tài)無(wú)法使用ModeisIM仿真),代表從器件收到數(shù)據(jù)并發(fā)送應(yīng)答位。接著主端口再發(fā)送要配置的寄存器地址表示寄存器Ox32二進(jìn)制為(00110010),Ox32是OV7670內(nèi)寄存器地址,從高位發(fā)到低位,然后重復(fù)上述操作。然后主端口設(shè)備發(fā)送要配置的數(shù)據(jù)Oxb2二進(jìn)制數(shù)為(10110010),也是重復(fù)上述操作。最后,主端口再發(fā)送一位結(jié)束標(biāo)志位即I2C_sclk保持高電平,I2C_sdat線上升沿,代表16位數(shù)據(jù)已經(jīng)寫(xiě)完,OV7670內(nèi)部的寄存器Ox32里的數(shù)值為Oxb2。 以上介紹如何配置了一個(gè)寄存器數(shù)據(jù)的詳細(xì)過(guò)程。本設(shè)計(jì)要配置的寄存器有164個(gè),就不一一贅述了。下面通過(guò)表列出幾個(gè)重要的寄存器。除了表3-1中列出這幾個(gè)寄存器,其它寄存器采用默認(rèn)值。幾個(gè)重要的寄存器數(shù)據(jù)配置寄存器地址功能描述設(shè)定值設(shè)定功能12選擇圖像輸出格式04RGB565格式輸出11時(shí)鐘輸入設(shè)置80使用外部時(shí)鐘6BPLL寄存器設(shè)置00選擇0分頻3EPCLK像素時(shí)鐘設(shè)置00選擇0分頻全屏最大基于SDRAM的視頻處理顯示模塊VGA驅(qū)動(dòng)程序設(shè)計(jì)經(jīng)過(guò)處理之后的YUV格式的視頻要經(jīng)過(guò)VGA驅(qū)動(dòng)程序才能真正顯示在VGA顯示器上,該程序RTL原理圖VGA驅(qū)動(dòng)程序原理圖原理圖各引腳功能介紹:CLK是接的全局時(shí)鐘取反。rst_n是復(fù)位信號(hào)。lcd_data[15..0]是要顯示的經(jīng)過(guò)處理的存儲(chǔ)在SDRAM里的YUV格式數(shù)據(jù)。lcd_dclk是像素時(shí)鐘信號(hào)。lcd_hs是行掃描。lcd_vs是場(chǎng)掃描。lcd_en是顯示屏使能信號(hào),高電平輸出輸入數(shù)據(jù)lcd_data。lcd_rgb[15..0]是輸出信號(hào)。lcd_xpos是顯示水平坐標(biāo)。lcd_ypos是顯示垂直坐標(biāo)。lcd_request是輸出坐標(biāo)請(qǐng)求信號(hào),高電平時(shí)輸出坐標(biāo)。lcd_framesync就是場(chǎng)掃描。lcd_blank是行掃描與場(chǎng)掃描,空白信號(hào)。這個(gè)模塊凡是需要VGA顯示的,都會(huì)用到,程序不再詳細(xì)分析。只要根據(jù)分辨率設(shè)置場(chǎng)消隱期場(chǎng)、消隱后肩、場(chǎng)顯示期和域場(chǎng)消隱前肩的四個(gè)時(shí)期的時(shí)間就可以了。行掃描和場(chǎng)掃描時(shí)序圖 如上圖所示。VGA顯示一直在掃描,每一場(chǎng)的掃描由若干行掃描組成,如此循環(huán)下去。將場(chǎng)掃描分為四個(gè)階段由圖3-12得出場(chǎng)掃描可以分為a、b、c、d,4個(gè)階段。這四個(gè)階段定義如下:a~b:場(chǎng)消隱期。b~c:場(chǎng)消隱后肩。c~d:場(chǎng)顯示期。d~e:場(chǎng)消隱前肩。 分辨率640*480的時(shí)間參數(shù)設(shè)置如下`define H_FRONT 11'd16`define H_SYNC 11'd96`define H_BACK 11'd48`define H_DISP 11'd640`define H_TOTAL 11'd800 `define V_FRONT 11'd10`define V_SYNC 11'd2`define V_BACK 11'd33`define V_DISP 11'd480`define V_TOTAL 11'd525視頻數(shù)據(jù)格式轉(zhuǎn)換程序設(shè)計(jì)經(jīng)過(guò)攝像頭采集模塊之后,輸出的是RGB565格式的視頻,因?yàn)橄啾扔诓噬曨l灰度視頻比較好處理。所以要把RGB565格式視頻轉(zhuǎn)化為YUV的灰度視頻,還得先在兩者之間加入RGB888格式的轉(zhuǎn)化。而這一轉(zhuǎn)換只需要通過(guò)簡(jiǎn)單的高位補(bǔ)低位或者低位補(bǔ)零就可以實(shí)現(xiàn)。為保障數(shù)據(jù)的精確度采取高位補(bǔ)低位的方法進(jìn)行處理。實(shí)現(xiàn)編碼如下: RGB888_R<={cmos_indata[15:11],cmos_indata[15:13]} RGB888_G<={cmos_indata[10:5],cmos_indata[10:9]} RGB888_B<={cmos_indata[4:0],cmos_indata[4:2]} RGB顏色格式轉(zhuǎn)YUV格式,實(shí)際上是色度空間的轉(zhuǎn)換,RGB是三基色度空間,YUV是亮度與色度的表達(dá),具體的公式如下:Y=0.299R+0.587G=0.114B(1-a)Cb=0.568B-Y+128=-0.172R-0.339G+0.511B+128(Cr=0.713B-Y+128=0.511R-0.428G-0.083B+128 但是FPGA是0和1的世界,Verilog語(yǔ)言是不能對(duì)浮點(diǎn)數(shù)進(jìn)行計(jì)算,所以我們先把這些乘數(shù)等值擴(kuò)大256倍,再向右移位8位,來(lái)實(shí)現(xiàn)同樣的計(jì)算結(jié)果,轉(zhuǎn)換后的公式如下:Y=77*R+150*G+29*B?8Cb=-43*R-85*G+128*B?8+128Cr=128*R-107*G-21*B?8 雖然FPGA有著資源豐富的乘法器和移位寄存器,如果直接用直白的公式按上面的運(yùn)算來(lái)編碼,也是可以計(jì)算出最后想要的結(jié)果。但是這樣執(zhí)行的效率就低、資源消耗巨大;并且在表達(dá)式為負(fù)數(shù)的時(shí)候,運(yùn)算結(jié)果容易出錯(cuò)。因此,我們?cè)诎阉惴▽?shí)際表達(dá)寫(xiě)進(jìn)FPGA程序的時(shí)候,我們需要把運(yùn)算進(jìn)行拆分。本設(shè)計(jì)先進(jìn)行了各個(gè)乘數(shù)的運(yùn)算,再進(jìn)行相加減。并且為了避免運(yùn)算過(guò)程出現(xiàn)負(fù)數(shù)而徒增麻煩的情況,先把得到的加減數(shù)加上128,也就是提到括號(hào)運(yùn)算內(nèi),再進(jìn)行移位。這樣大大避免了結(jié)果溢出的風(fēng)險(xiǎn)。公式如下。Y=77*R+150*G+29*B?8 Cb=-43*R-85*G+128*B+32768?8 Cr=128*R-107*G-21*B+32768?8 最后的移位我們直接采取提取首八位數(shù)據(jù)輸出的方法,編碼如下。 Y_r1 <= Y_r0[15:8]; Cb_r1 <= Cb_r0[15:8]; Cr_r1 <= Cr_r0[15:8]; 經(jīng)過(guò)如上各個(gè)步驟的計(jì)算后即可得到灰度信號(hào),實(shí)際上需要處理及輸出的僅一項(xiàng)8Bit的灰度信號(hào)Y。SDRAM緩存模塊設(shè)計(jì)因?yàn)閷?shí)時(shí)的視頻采集系統(tǒng)所要處理的數(shù)據(jù)量十分大,而且對(duì)實(shí)時(shí)性要求高,最重要的是采集視頻的速度和處理數(shù)據(jù)的速度可能會(huì)不匹配,所以就需要高速、容量大的存儲(chǔ)器來(lái)緩存實(shí)時(shí)的視頻數(shù)據(jù),實(shí)現(xiàn)數(shù)據(jù)的緩存和處理速度盡可能匹配。SDRAM(SynchronousDynamicRandomAccessMemory,同步動(dòng)態(tài)隨機(jī)存儲(chǔ)器),同步是指內(nèi)存工作需要同步時(shí)鐘,內(nèi)部的命令的發(fā)送與數(shù)據(jù)的傳輸都以它為基準(zhǔn);動(dòng)態(tài)是指存儲(chǔ)陣列需要不斷的刷新來(lái)保證數(shù)據(jù)不丟失;隨機(jī)是指數(shù)據(jù)不是線性依次存儲(chǔ),而是自由指定地址進(jìn)行數(shù)據(jù)讀寫(xiě)。內(nèi)部本質(zhì)是一個(gè)存儲(chǔ)陣列,把對(duì)應(yīng)數(shù)據(jù)一個(gè)一個(gè)放入格子內(nèi)。參照定位原理的形式,先選擇一行(行),然后選擇列(列),使存儲(chǔ)單元確定。以內(nèi)存的角度說(shuō),那些單元格被稱為存儲(chǔ)單元,每一個(gè)存儲(chǔ)單元最大能裝載大小為8、16、32的數(shù)據(jù)。而對(duì)于整個(gè)行列組成的塊而言,整個(gè)存儲(chǔ)陣列在SDRAM中被稱為邏輯Bank(LogicalBank)。SDRAM存儲(chǔ)陣列 在介紹了基本硬件構(gòu)成之后,再來(lái)介紹本設(shè)計(jì)頂層控制模塊。其原理圖如下。SDRAM頂層控制模塊SDRAM各引腳說(shuō)明引腳說(shuō)明clk_refSDRAM控制器時(shí)鐘輸入clk_refoutSDRAM驅(qū)動(dòng)時(shí)鐘輸入rst_nSDRAM控制器復(fù)位信號(hào)輸入sdram_clkSDRAM驅(qū)動(dòng)時(shí)鐘信號(hào)接口sdram_ckeSDRAM驅(qū)動(dòng)時(shí)鐘使能信號(hào)接口sdram_cs_nSDRAM芯片片選使能信號(hào)接口sdram_we_nSDRAM數(shù)據(jù)寫(xiě)入使能信號(hào)接口sdram_cas_nSDRAM列地址選通信號(hào)接口sdram_ras_nSDRAM行地址選通信號(hào)接口sdram_init_doneSDRAM初始化完成信號(hào),作為外部數(shù)據(jù)輸入的前提wr_loadSDRAM寫(xiě)地址置位信號(hào)wr_addrSDRAM寫(xiě)入地址最小值wr_max_addrSDRAM寫(xiě)入地址最大值wr_lengthSDRAM寫(xiě)入數(shù)據(jù)長(zhǎng)度rd_addrSDRAM讀取地址最小值rd_max_addrSDRAM讀取地址最大值rd_lengthSDRAM讀取數(shù)據(jù)長(zhǎng)度sys_weWRFIFO數(shù)據(jù)輸入信號(hào)clk_writeWRFIFO輸入端時(shí)鐘信號(hào)sys_rdRDFIFO輸出端時(shí)鐘信號(hào)clk_readRDFIFO數(shù)據(jù)讀取信號(hào)對(duì)于用戶的操作而言,只需要關(guān)心WRFIFO寫(xiě)入端口,與RDFIFO讀取端
口。每個(gè)端口的時(shí)序均一樣,主要分為連續(xù)寫(xiě)入/讀取,與使能寫(xiě)入/讀取。寫(xiě)入SDRAM時(shí)序圖但是實(shí)際上我們是在同一個(gè)Bank當(dāng)中讀寫(xiě)SDRAM緩存,這會(huì)使得當(dāng)前正在進(jìn)行的圖像數(shù)據(jù)與上一次存入的圖像數(shù)據(jù)之間存在重疊。為了解決這個(gè)問(wèn)題,需要在實(shí)現(xiàn)乒乓操作,使得在一段時(shí)間內(nèi),SDRAM存儲(chǔ)塊進(jìn)行讀寫(xiě)的乒乓操作:乒乓讀寫(xiě)操作圖 在編碼中添加了2個(gè)先入先出隊(duì)列,通過(guò)數(shù)據(jù)緩存模塊實(shí)現(xiàn)了1+2Bank與3+4Bank數(shù)據(jù)在一定時(shí)間內(nèi),SDRAM儲(chǔ)存塊讀寫(xiě)的乒乓操作。同時(shí)還通過(guò)控制使能信號(hào)的高低電平,來(lái)實(shí)現(xiàn)控制是否執(zhí)行SDRAM控制器乒乓操作。目標(biāo)識(shí)別模塊設(shè)計(jì) 本設(shè)計(jì)在比較了上面的三種方法之后,決定采用幀間差分法實(shí)現(xiàn)本設(shè)計(jì)。一幀圖像分辨率為640*480,如果要將每一像素相加,假如每位像素都為8位1的,即最大值為78643200,F(xiàn)PGA開(kāi)發(fā)板內(nèi)部寄存器是可以接受的。 模塊的功能是計(jì)算每一幀里所有像素的和,將相鄰兩幀的和比較大小,然后用比較大的數(shù)據(jù)減去相對(duì)小的數(shù)據(jù),最后將相減后的數(shù)與固定閾值比較,最后將相減后的數(shù)和固定閾值比較,這里設(shè)置閾值是e5ffff。當(dāng)大于閾值時(shí),輸出0,使LED燈亮,表示有運(yùn)動(dòng)目標(biāo)。當(dāng)小于時(shí),輸出1,LED燈滅,表示靜止。圖3-17目標(biāo)識(shí)別模塊附錄附錄附錄 總系統(tǒng)頂層程序:`timescale1ns/1psmodulesdram_ov7670_vga( //globalclock50MHz //input clk_27, //27MHz input CLOCK, //sdramcontrol output S_CLK, //sdramclock output S_CKE, //sdramclockenable output S_NCS, //sdramchipselect output S_NWE, //sdramwriteenable output S_NCAS, //sdramcolumnaddressstrobe output S_NRAS, //sdramrowaddressstrobe output[1:0] S_DQM, //sdramdataenable output [1:0] S_BA, //sdrambankaddress output [11:0] S_A, //sdramaddress inout [15:0] S_DB, //sdramdata //VGAport output VGA_HSYNC, //horizontalsync output VGA_VSYNC, //verticalsync output [15:0] VGAD, //VGAdata //cmosinterface output CMOS_SCLK, //cmosi2cclock inout CMOS_SDAT, //cmosi2cdata input CMOS_VSYNC, //cmosvsync input CMOS_HREF, //cmoshsyncrefrence input CMOS_PCLK, //cmospxielclock output CMOS_XCLK, //cmosexternlclock input [7:0] CMOS_DB, //cmosdata outputled_o, output [3:0] LED //leddatainput );assignrst_n=1'b1;//wire clk_vga; //vgaclockwire clk_ref; //sdramctrlclockwire clk_refout; //sdramclockoutputwire sys_rst_n; //globalresetsystem_ctrl u_system_ctrl( .clk (CLOCK), //globalclock50MHZ .rst_n (rst_n), //externalreset .sys_rst_n (sys_rst_n), //globalreset .clk_c0 (clk_vga), //25MHz .clk_c1 (clk_ref), //100MHz-45deg .clk_c2 (clk_refout) //100MHz);//wire [7:0] I2C_RDATA; //i2cregisterdatawire [7:0] LUT_INDEX; //lutindexwire Config_Done; //I2Cconfigdone I2C_AV_Config u_I2C_AV_Config( //Globalclock .iCLK (clk_vga), //25MHz .iRST_N (sys_rst_n), //GlobalReset //I2CSide .I2C_SCLK (CMOS_SCLK), //I2CCLOCK .I2C_SDAT (CMOS_SDAT), //I2CDATA //CMOSSignal .Config_Done (Config_Done), //I2CConfigdone .I2C_RDATA (I2C_RDATA), //CMOSID .LUT_INDEX ()//(LUT_INDEX) //IDIndex);assign led_data=I2C_RDATA; //diaplayI2C_RDATA//wire frame_valid; //datavalid,oraddressrestartwire [7:0] cmos_fps_data; //cmosframerateCMOS_Capture u_CMOS_Capture( //GlobalClock .iCLK (clk_vga), //25MHz .iRST_N (sys_rst_n), //globalreset //I2CInitilizeDone .Init_Done (Config_Done&sdram_init_done), //InitDone //SensorInterface .CMOS_RST_N (),//(cmos_rst_n), //cmosworkstate .CMOS_PWDN (),//(cmos_pwdn), //cmospoweron .CMOS_XCLK (CMOS_XCLK), //cmos .CMOS_PCLK (CMOS_PCLK), //25MHz .CMOS_iDATA (CMOS_DB), //CMOSData .CMOS_VSYNC (CMOS_VSYNC), //L:Vaild .CMOS_HREF (CMOS_HREF), //H:Vaild //OuputSensorData .CMOS_oCLK (cmos_iclk), //DataPCLK .CMOS_oDATA (cmos_indata), //16BitsRGB .CMOS_VALID (cmos_VALID), //DataEnable .CMOS_FPS_DATA ()//(cmos_fps_data) //cmosframerate);wirecmos_VALID;wire [15:0] cmos_indata;wirecmos_iclk;//VIP_RGB888_YCbCr444VIP_RGB888_YCbCr444_inst( //globalclock .clk(clk_vga), //cmosvideopixelclock .rst_n(sys_rst_n), //globalreset .cmos_indata(cmos_indata), .cmos_iclk(cmos_iclk),.cmos_valid(cmos_VALID), .CMOS_oCLK(sys_we), //1/2PCLK .CMOS_oDATA(sys_data_in), //16BitsRGB .img_y(img_y), .CMOS_VALID(frame_valid) //DataEnable);wire [7:0]img_y;detectdetect_inst( .sclk (clk_vga), .cmos_iclk (sys_we), .rst_n (sys_rst_n), .image_y (img_y), .cmos_valid(frame_valid), .led_o(led_o));//sdramvgactrlsystemwire sys_we; //systemdatawriteenablewire [15:0] sys_data_in; //systemdatainputwire sdram_init_done; //sdraminitdonesdram_vga_top u_sdram_vga_top( //globalclock .clk_vga (clk_vga), //vgaclock .clk_ref (clk_ref), //sdramctrlclock .clk_refout (clk_refout), //sdramclockoutput .rst_n (sys_rst_n), //globalreset //sdramcontrol .sdram_clk (S_CLK), //sdramclock .sdram_cke (S_CKE), //sdramclockenable .sdram_cs_n (S_NCS), //sdramchipselect .sdram_we_n (S_NWE), //sdramwriteenable .sdram_cas_n (S_NCAS), //sdramcolumnaddressstrobe .sdram_ras_n (S_NRAS), //sdramrowaddressstrobe .sdram_udqm (S_DQM[1]), //sdramdataenable(H:8) .sdram_ldqm (S_DQM[0]), //sdramdataenable(L:8) .sdram_ba (S_BA), //sdrambankaddress .sdram_addr (S_A), //sdramaddress .sdram_data (S_DB), //sdramdata //lcdport .lcd_dclk (), //lcdpixelclock .lcd_hs (VGA_HSYNC), //lcdhorizontalsync .lcd_vs (VGA_VSYNC), //lcdverticalsync .lcd_sync (),//(lcd_sync), //lcdsync .lcd_blank (), //lcdblank(L:blank) .lcd_red (VGAD[15:11]), //lcdreddata .lcd_green (VGAD[10:5]), //lcdgreendata .lcd_blue (VGAD[4:0]), //lcdbluedata //userinterface .clk_write (clk_vga), //fifowriteclock .sys_we (sys_we), //fifowriteenable .sys_data_in (sys_data_in), //fifodatainput .sdram_init_done (sdram_init_done), //sdraminitdone .frame_valid (frame_valid) //framevalid);endmodule時(shí)鐘及復(fù)位模塊程序:`timescale1ns/1nsmodulesystem_ctrl( input clk, //50MHz input rst_n, //globalreset output sys_rst_n, //systemreset output clk_c0, output clk_c1, output clk_c2 //-75deg);////rst_nsynchronism,iscontrolledbytheinputclkregrst_nr1,rst_nr2;always@(posedgeclkornegedgerst_n)begin if(!rst_n) begin rst_nr1<=1'b0; rst_nr2<=1'b0; end else begin rst_nr1<=1'b1; rst_nr2<=rst_nr1; endend////componentinstantiationforsystem_delaywire delay_done;system_delay u_system_delay( .clk (clk), .rst_n (rst_nr2), .delay_done (delay_done));wire pll_rst=~rst_nr2&~delay_done; //activeHigh////Componentinstantiationwire locked; sdram_pll u_sdram_pll( .inclk0 (clk), .areset (pll_rst), .locked (locked), .c0 (clk_c0), .c1 (clk_c1), .c2 (clk_c2));////sys_rst_nsynchronism,iscontrolbythehighestoutputclkwire sysrst_nr0=rst_nr2&locked&delay_done;reg sysrst_nr1,sysrst_nr2;always@(posedgeclk_c1ornegedgesysrst_nr0)begin if(!sysrst_nr0)beginsysrst_nr1<=1'b0;sysrst_nr2<=1'b0;end elsebeginsysrst_nr1<=1'b1;sysrst_nr2<=sysrst_nr1;endendassignsys_rst_n=sysrst_nr2; //activeLowendmodulemodulesystem_delay( input clk, //50MHz input rst_n, output delay_done);////Delay100msforsteadystatelocalparam DELAY_CNT=23'd100_0000; //50msreg [22:0]cnt;always@(posedgeclkornegedgerst_n)begin if(!rst_n) cnt<=0; else begin if(cnt<DELAY_CNT)//1ms cnt<=cnt+1'b1; else cnt<=cnt; endend////sys_rst_nsynchronismassign delay_done=(cnt==DELAY_CNT)?1'b1:1'b0;endmodule攝像頭數(shù)據(jù)采集模塊程序:`timescale1ns/1nsmoduleCMOS_Capture( //GlobalClock input iCLK, //25MHz input iRST_N,//I2CInitilizeDoneinput Init_Done, //InitDone //SensorInterface output CMOS_RST_N, //cmosworkstate(5msdelayforsccbconfig) output CMOS_PWDN,//cmospoweron output CMOS_XCLK, //25MHz input CMOS_PCLK, //25MHz input [7:0] CMOS_iDATA, //CMOSData input CMOS_VSYNC, //L:Vaild input CMOS_HREF, //H:Vaild //OuputSensorData output reg CMOS_oCLK, //1/2PCLK output reg [15:0] CMOS_oDATA, //16BitsRGB output reg CMOS_VALID, //DataEnable output reg [7:0] CMOS_FPS_DATA //cmosfps);assign CMOS_RST_N=1'b1; //cmosworkstate(5msdelayforsccbconfig)assignCMOS_PWDN=1'b0; //cmospoweron assign CMOS_XCLK=iCLK; //25MHzXCLK//reg mCMOS_HREF; //行同步:高電平有效always@(posedgeCMOS_PCLKornegedgeiRST_N)begin if(!iRST_N) mCMOS_HREF<=0; else mCMOS_HREF<=CMOS_HREF; endwire CMOS_HREF_over=({mCMOS_HREF,CMOS_HREF}==2'b10)?1'b1:1'b0; //HREF下降沿結(jié)束*///reg mCMOS_VSYNC;always@(posedgeCMOS_PCLKornegedgeiRST_N)begin if(!iRST_N) mCMOS_VSYNC<=1; else mCMOS_VSYNC<=CMOS_VSYNC; //場(chǎng)同步:低電平有效endwire CMOS_VSYNC_over=({mCMOS_VSYNC,CMOS_VSYNC}==2'b01)?1'b1:1'b0; //VSYNC上升沿結(jié)束////CountertheHS&VSPixellocalparam H_DISP = 12'd640;localparam V_DISP = 12'd480;reg [11:0] X_Cont; //640reg [11:0] Y_Cont; //480always@(posedgeCMOS_PCLKornegedgeiRST_N)begin if(!iRST_N) X_Cont<=0; elseif(~CMOS_VSYNC&CMOS_HREF) //場(chǎng)信號(hào)有效 X_Cont<=(byte_state==1'b1)?X_Cont+1'b1:X_Cont; else X_Cont<=0;endalways@(posedgeCMOS_PCLKornegedgeiRST_N)begin if(!iRST_N) Y_Cont<=0; elseif(CMOS_VSYNC==1'b0) begin if(CMOS_HREF_over==1'b1) //HREF下降沿一行結(jié)束 Y_Cont<=Y_Cont+1'b1; end else Y_Cont<=0;end*/////Changethesensordatafrom8bitsto16bits.reg byte_state; //bytestatecountreg[7:0] Pre_CMOS_iDATA;always@(posedgeCMOS_PCLKornegedgeiRST_N)begin if(!iRST_N) begin byte_state<=0; Pre_CMOS_iDATA<=8'd0; CMOS_oDATA<=16'd0; end else begin if(~CMOS_VSYNC&CMOS_HREF) //行場(chǎng)有效,{first_byte,second_byte} begin byte_state<=byte_state+1'b1; //(RGB565={first_byte,second_byte}) case(byte_state) 1'b0: Pre_CMOS_iDATA[7:0]<=CMOS_iDATA; 1'b1: CMOS_oDATA[15:0]<={Pre_CMOS_iDATA[7:0],CMOS_iDATA[7:0]}; endcase end else begin byte_state<=0; Pre_CMOS_iDATA<=8'd0; CMOS_oDATA<=CMOS_oDATA; end endend////WaitforSensoroutputDatavalid,10Franmereg [3:0] Frame_Cont;reg Frame_valid;always@(posedgeCMOS_PCLKornegedgeiRST_N)begin if(!iRST_N) begin Frame_Cont<=0; Frame_valid<=0; end elseif(Init_Done) //CMOSI2C初始化完畢 begin if(CMOS_VSYNC_over==1'b1) //VS上升沿,1幀寫(xiě)入完畢 begin if(Frame_Cont<12) begin Frame_Cont <= Frame_Cont+1'b1; Frame_valid<=1'b0; end else begin Frame_Cont <= Frame_Cont; Frame_valid<=1'b1; //數(shù)據(jù)輸出有效 end end endend////CMOS_DATA數(shù)據(jù)同步輸出使能時(shí)鐘always@(posedgeCMOS_PCLKornegedgeiRST_N)begin if(!iRST_N) CMOS_oCLK<=0; elseif(Frame_valid==1'b1&&byte_state)//(X_Cont>=12'd1&&X_Cont<=H_DISP)) CMOS_oCLK<=~CMOS_oCLK; else CMOS_oCLK<=0;end////數(shù)據(jù)輸出有效CMOS_VALIDalways@(posedgeCMOS_PCLKornegedgeiRST_N)begin if(!iRST_N) CMOS_VALID<=0; elseif(Frame_valid==1'b1) CMOS_VALID<=~CMOS_VSYNC; else CMOS_VALID<=0;end//// 2s延時(shí)函數(shù)reg [25:0] delay_cnt; //25_000000*2always@(posedgeiCLKornegedgeiRST_N)begin if(!iRST_N) delay_cnt<=0; elseif(Frame_valid) begin if(delay_cnt<26'd50_000000) delay_cnt<=delay_cnt+1'b1; else delay_cnt<=0; end else delay_cnt<=0;endwire delay_2s=(delay_cnt==26'd50_000000)?1'b1:1'b0;////幀率采樣計(jì)算reg fps_state;reg [7:0] fps_data;always@(posedgeiCLKornegedgeiRST_N)begin if(!iRST_N) begin fps_data<=0; fps_state<=0; CMOS_FPS_DATA<=0; end elseif(Frame_valid) begin case(fps_state) 0: begin CMOS_FPS_DATA<=CMOS_FPS_DATA; if(delay_2s==0) begin fps_state<=0; if(CMOS_VSYNC_over==1'b1) //VS上升沿,1幀寫(xiě)入完畢 fps_data<=fps_data+1'b1; end else fps_state<=1; end 1: begin fps_state<=0; fps_data<=0; CMOS_FPS_DATA<=fps_data>>1; end endcase end else begin fps_data<=0; fps_state<=0; CMOS_FPS_DATA<=0; endendendmodule視頻數(shù)據(jù)格式轉(zhuǎn)換模塊程序:`timescale1ns/1nsmoduleVIP_RGB888_YCbCr444( //globalclock input clk, //cmosvideopixelclock input rst_n, //globalreset inputwire[15:0]cmos_indata, inputwirecmos_iclk, inputwirecmos_valid,output wire CMOS_oCLK, //1/2PCLK output wire [15:0] CMOS_oDATA, //16BitsRGB output wire CMOS_VALID //DataEnable);///*********************************************//Referto<OV7725CameraModuleSoftwareApplicatonNote>page5 Y = (77*R + 150*G + 29*B)>>8 Cb = (-43*R - 85*G + 128*B)>>8+128 Cr = (128*R - 107*G - 21*B)>>8+128> Y = (77*R + 150*G + 29*B)>>8 Cb = (-43*R - 85*G + 128*B+32768)>>8 Cr = (128*R - 107*G - 21*B+32768)>>8**********************************************///Step1reg [15:0] img_red_r0, img_red_r1, img_red_r2; reg [15:0] img_green_r0, img_green_r1, img_green_r2;reg [15:0] img_blue_r0, img_blue_r1, img_blue_r2;always@(posedgeclkornegedgerst_n)begin if(!rst_n) begin img_red_r0 <= 0; img_red_r1 <= 0; img_red_r2 <= 0; img_green_r0 <= 0; img_green_r1 <= 0; img_green_r2 <= 0; img_blue_r0 <= 0; img_blue_r1 <= 0; img_blue_r2 <= 0; end else begin img_red_r0 <= {cmos_indata[15:11],cmos_indata[15:13]} * 8'd77; img_red_r1 <= {cmos_indata[15:11],cmos_indata[15:13]} * 8'd43; img_red_r2 <= {cmos_indata[15:11],cmos_indata[15:13]} * 8'd128; img_green_r0 <= {cmos_indata[10:5],cmos_indata[10:9]} * 8'd150; img_green_r1 <= {cmos_indata[10:5],cmos_indata[10:9]} * 8'd85; img_green_r2 <= {cmos_indata[10:5],cmos_indata[10:9]} * 8'd107; img_blue_r0 <= {cmos_indata[4:0],cmos_indata[4:2]} * 8'd29; img_blue_r1 <= {cmos_indata[4:0],cmos_indata[4:2]} * 8'd128; img_blue_r2 <= {cmos_indata[4:0],cmos_indata[4:2]} * 8'd21; endend////Step2reg [15:0] img_Y_r0; reg [15:0] img_Cb_r0;reg [15:0] img_Cr_r0;always@(posedgeclkornegedgerst_n)begin if(!rst_n) begin img_Y_r0 <= 0; img_Cb_r0 <= 0; img_Cr_r0 <= 0; end else begin img_Y_r0 <= img_red_r0 + img_green_r0 + img_blue_r0; img_Cb_r0 <= img_blue_r1- img_red_r1 - img_green_r1 + 16'd32768; img_Cr_r0 <= img_red_r2 + img_green_r2 + img_blue_r2 + 16'd32768; endend////Step3reg [7:0] img_Y_r1; reg [7:0] img_Cb_r1;reg [7:0] img_Cr_r1;always@(posedgeclkornegedgerst_n)begin if(!rst_n) begin img_Y_r1 <= 0; img_Cb_r1 <= 0; img_Cr_r1 <= 0; end else begin img_Y_r1 <= img_Y_r0[15:8]; img_Cb_r1 <= img_Cb_r0[15:8]; img_Cr_r1 <= img_Cr_r0[15:8]; endend////lag3clockssignalsyncreg [2:0] cmos_iclk_r;reg [2:0] cmos_valid_r; always@(posedgeclkornegedgerst_n)begin if(!rst_n) begin cmos_iclk_r<=0; cmos_valid_r<=0; end else begin cmos_iclk_r <= {cmos_iclk_r[1:0], cmos_iclk}; cmos_valid_r <= {cmos_valid_r[1:0], cmos_valid}; endendassign CMOS_oCLK = cmos_iclk_r[2];assign CMOS_VALID = cmos_valid_r[2];assignCMOS_oDATA={img_Y_r1[7:3],img_Y_r1[7:2],img_Y_r1[7:3]};endmodule目標(biāo)識(shí)別模塊:moduledetect( input wire sclk, input wire cmos_iclk, input wire rst_n, input wire [7:0] image_y, input wire cmos_valid, output wire led_o);parameterYUZHI = 28'he5fffff;reg [27:0] cnt_1;reg[27:0] cnt_2;reg [27:0] cnt_3;reg led_o_r;//reg [27:0] cnt_4;reg cmos_valid_r1,cmos_valid_r2;wirenegedge_valid;always@(posedgesclkornegedgerst_n) if(rst_n==1'b0)begin cmos_valid_r1<='b0; cmos_valid_r2<='b0; end elsebegin cmos_valid_r1<=cmos_valid; cmos_valid_r2<=cmos_valid_r1; end assignnegedge_valid=~cmos_valid_r1&cmos_valid_r2;assignposedge_valid=cmos_valid_r1&~cmos_valid_r2; always@(posedgecmos_iclkornegedgerst_n) if(rst_n==1'b0) cnt_1<='b0; elseif(cmos_valid==1'b1) cnt_1<=cnt_1+image_y; else cnt_1<=cnt_1;always@(posedgesclkornegedgerst_n) if(rst_n==1'b0) cnt_2<='b0; elseif(posedge_valid==1'b1) cnt_2<=cnt_1; always@(posedgesclkornegedgerst_n) if(rst_n==1'b0) cnt_3<='b0; elseif(negedge_valid==1'b1)begin if(cnt_1>cnt_2) cnt_3<=cnt_1-cnt_2; else cnt_3<=cnt_2-cnt_1; end always@(posedgesclkornegedgerst_n) if(rst_n==1'b0) led_o_r<=1'b1; elseif(cnt_3>YUZHI) led_o_r<=1'b0; else led_o_r<=1'b1; assignled_o=led_o_r;endmoduleOV7670圖像傳感器初始化配置模塊`timescale1ns/1nsmoduleI2C_AV_Config( //Globalclock input iCLK, //25MHz input iRST_N, //GlobalReset //I2CSide output I2C_SCLK, //I2CCLOCK inout I2C_SDAT, //I2CDATA output reg Config_Done,//ConfigDone output reg [7:0] LUT_INDEX, //LUTIndex output [7:0] I2C_RDATA //I2CReadData);// LUTDataNumberparameter LUT_SIZE = 168;///////////////////// I2CControlClock ////////////////////////// ClockSettingparameter CLK_Freq = 25_000000; //25MHzparameter I2C_Freq = 10_000; //10KHzreg [15:0] mI2C_CLK_DIV; //CLKDIVreg mI2C_CTRL_CLK; //I2CControlClockalways@(posedgeiCLKornegedgeiRST_N)begin if(!iRST_N) begin mI2C_CLK_DIV <= 0; mI2C_CTRL_CLK <= 0; end else begin if(mI2C_CLK_DIV <(CLK_Freq/I2C_Freq)/2) mI2C_CLK_DIV <= mI2C_CLK_DIV+1'd1; else begin mI2C_CLK_DIV <= 0; mI2C_CTRL_CLK <= ~mI2C_CTRL_CLK; end endend//reg i2c_en_r0,i2c_en_r1;always@(posedgeiCLKornegedgeiRST_N)begin if(!iRST_N) begin i2c_en_r0<=0; i2c_en_r1<=0; end else begin i2c_en_r0<=mI2C_CTRL_CLK; i2c_en_r1<=i2c_en_r0; endendwire i2c_negclk=(i2c_en_r1&~i2c_en_r0)?1'b1:1'b0; //negedgei2c_sclktransferdata////////////////////// ConfigControl //////////////////////////////InternalRegisters/Wires//reg [23:0] mI2C_DATA; //I2CDatawire mI2C_END; //I2CTransferEndwire mI2C_ACK; //I2CTransfer
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 修理廠合同范例
- 多人勞動(dòng)合同范例
- 信用證合同范例英文
- 廬陽(yáng)區(qū)代理記賬合同范例
- 婚慶物資采購(gòu)合同范例
- 鄉(xiāng)鎮(zhèn)餐飲轉(zhuǎn)讓合同范例
- 信陽(yáng)勞動(dòng)合同范例
- 山東省勞動(dòng)合同范例
- 工人安裝費(fèi)合同范例
- 學(xué)徒店供料合同模板
- 成人住院患者靜脈血栓栓塞癥Caprini、Padua風(fēng)險(xiǎn)評(píng)估量表
- 排球《正面上手發(fā)球》教案
- 股骨粗隆間骨折
- 小班安全我要跟著老師走
- (正式版)JBT 14795-2024 內(nèi)燃機(jī)禁用物質(zhì)要求
- 基于核心素養(yǎng)初中數(shù)學(xué)跨學(xué)科教學(xué)融合策略
- 200TEU 長(zhǎng)江集裝箱船設(shè)計(jì)
- 辦公樓物業(yè)服務(wù)管理的培訓(xùn)
- 智慧能源管理平臺(tái)建設(shè)項(xiàng)目解決方案
- JTG∕T F30-2014 公路水泥混凝土路面施工技術(shù)細(xì)則
- 2024年高中語(yǔ)文學(xué)業(yè)水平過(guò)關(guān)測(cè)試四-名句名篇默寫(xiě)積累過(guò)關(guān)訓(xùn)練(全國(guó)通用)學(xué)生版
評(píng)論
0/150
提交評(píng)論