
簡介本資源是一套基于FPGA EP4CE10平臺實現(xiàn)OV5640攝像頭圖像采集與HDMI實時顯示的完整Verilog HDL工程面向數(shù)字電路、嵌入式圖像系統(tǒng)及FPGA初學者與進階開發(fā)者解決從傳感器驅(qū)動、數(shù)據(jù)流控制到高清視頻輸出的一體化硬件設計難題。壓縮包共261個文件含56個.cdb編譯數(shù)據(jù)庫、55個.hdb層次化數(shù)據(jù)庫、28個.v核心Verilog源碼涵蓋OV5640初始化、MIPI/DCMI時序控制、幀緩存、HDMI TMDS編碼與同步信號生成等模塊以及.qsf約束文件、.sof配置文件、.qpf工程文件和詳細readme說明總大小8.31MB。已有162人學習下載工程可直接在Quartus II中編譯燒錄無需額外適配讀者可獲得結(jié)構(gòu)清晰的多層級模塊劃分、I2C配置寄存器表、HDMI像素時鐘與色彩空間轉(zhuǎn)換邏輯、以及實測可用的軟硬件協(xié)同調(diào)試方案是掌握FPGA圖像采集系統(tǒng)開發(fā)的高復用性實踐范例。 前陣子整理工程歸檔時翻出這個項目挺典型的一塊EP4CE10入門級FPGA接一個OV5640攝像頭模組用Verilog HDL寫完整套邏輯最終把實時畫面通過HDMI輸出到顯示器上。項目不大但鏈路很長——從SCCB配置、DVP采集、跨時鐘域緩存到顯示時序生成幾乎把FPGA圖像處理的基礎環(huán)節(jié)都踩了一遍。這篇把整個方案、選型邏輯、代碼結(jié)構(gòu)和調(diào)試過程中踩過的坑都整理出來給準備做同類項目的朋友一個參考。如果你正好想入門FPGA圖像處理千萬別一上來就碰Zynq、MPSOC這些大平臺。EP4CE10加一顆OV5640花兩三百塊錢就能把“攝像頭采集到HDMI顯示”這條完整通路跑起來。這里面每個模塊單獨拆出來都不難但組合在一起幾乎把FPGA開發(fā)中最核心的能力都練到了時序設計、跨時鐘域處理、狀態(tài)機、IP核使用、時序約束。1. 項目方案與關(guān)鍵選型為什么EP4CE10能扛下這套系統(tǒng)1.1 一套入門級FPGA能做到的極限先說清楚EP4CE10是什么貨色。這顆芯片是Altera現(xiàn)在叫Intel PSGCyclone IV系列里的低端型號邏輯單元大約10320個嵌入式RAM約414Kbit也就是50多KBPLL兩個沒有硬核處理器、沒有DDR控制器、沒有任何視頻專用接口。聽著很寒酸但做視頻通路恰恰夠用因為視頻處理絕大部分工作不是“算”而是“搬”。什么叫“搬”把攝像頭送來的像素數(shù)據(jù)按節(jié)拍接住存進FIFO再按顯示器的節(jié)奏送出去。這個過程里幾乎沒有乘加運算不需要DSP不涉及復雜算法只考驗你對信號的時序控制能力。OV5640這類DVP接口攝像頭輸出的是并行的8位或10位數(shù)據(jù)加PCLK、VSYNC、HREF三個同步信號數(shù)據(jù)流是單向的、連續(xù)的、節(jié)奏穩(wěn)定的非常適合用狀態(tài)機處理。我當時選這個組合的邏輯很簡單一是為了避開MIPIOV5640雖然也支持MIPI但MIPI在FPGA上用起來麻煩需要高速串行接收EP4CE10不是干這個的料二是DVP并口邏輯清晰每個信號都能用示波器或邏輯分析儀去量對學生黨友好三是EP4CE10開發(fā)板便宜折騰壞了不心疼。如果你有正點原子、小梅哥、黑金這類常見的EP4CE10板子基本都能直接照著接。1.2 HDMI輸出的三條路線EP4CE10怎么選把圖像數(shù)據(jù)變成HDMI信號有三個層次的路線一定要先想清楚再動手。第一條路線是接一顆RGB轉(zhuǎn)HDMI的發(fā)送芯片比如ADV7513、SiI9134、CH7034B。FPGA只負責輸出并行RGB數(shù)據(jù)、行場同步、數(shù)據(jù)使能DE和像素時鐘編碼和串行化全交給芯片。這種方式FPGA邏輯資源占用最少調(diào)試也簡單缺點是板子上要多一顆芯片涉及實際布線不適合純學習環(huán)境。第二條路線是FPC直接驅(qū)動HDMI也就是用FPGA的LVDS差分IO去輸出TMDS信號自己實現(xiàn)DVI/HDMI的編碼。EP4CE10的差分IO標稱速率約840Mbps720p的三條數(shù)據(jù)通道各742.5Mbps理論在范圍內(nèi)。但這條路有幾個坎引腳分配受限不是每個bank都支持LVDS標準需要外部電阻做差分端接PCB差分走線要等長、控阻抗還要自己寫8b/10b編碼器。難度直線上升但對理解HDMI協(xié)議幫助巨大。第三條是直接用帶HDMI硬核的SoC那就跟EP4CE10沒關(guān)系了不在討論范圍內(nèi)。我的意見很明確如果你目標是“快速把完整視頻通路跑起來”選第一條用現(xiàn)成的RGB轉(zhuǎn)HDMI芯片把精力留給攝像頭采集鏈路如果你目標是“研究HDMI協(xié)議本身”選第二條但要做好連續(xù)調(diào)試幾周的準備。我下面的內(nèi)容以第一條路線為主因為對EP4CE10來說最現(xiàn)實也最適合大部分人一步一個腳印地學習。1.3 分辨率和緩存賬事前必須算清楚選分辨率不是拍腦袋要算帶寬和存儲。720p60的像素時鐘是74.25MHzRGB565每像素16bit數(shù)據(jù)率約1.19GbpsEP4CE10的普通IO跑74.25MHz綽綽有余。1080p60的像素時鐘是148.5MHz數(shù)據(jù)率約2.38GbpsEP4CE10勉強能跑但留給時序余量非常小入門階段不建議碰。更大的瓶頸是緩存。720p一幀RGB565是1280×720×21.8MBEP4CE10內(nèi)部只有約51KB壓根放不下一幀。所以必須用行緩存方案采集一行存進FIFO再由顯示時序讀出來。這種方式在圖像快速運動時偶爾會出現(xiàn)撕裂但靜止或慢速場景下幾乎看不出來。要真正解決幀同步問題就得外掛SDRAM或DDR那是第二階段的事先別貪多。如果存儲資源不夠還有一種常見做法是降低輸出分辨率比如640×48060一幀只有614KB依然放不下但行緩存壓力小很多調(diào)試會更輕松。我建議第一次做這個項目從640×480起步跑通了再上720p。2. 硬件連接與引腳規(guī)劃讓FPGA、攝像頭和HDMI芯片“對齊”2.1 信號定義與引腳分配硬件連接是整件事里最“瑣碎但決定成敗”的部分。OV5640模組接口一般有這些信號SIO_CI2C時鐘、SIO_DI2C數(shù)據(jù)、VSYNC幀同步、HREF行有效、PCLK像素時鐘、D0~D7數(shù)據(jù)、MCLK主時鐘輸入、RESET、PWDN。RGB轉(zhuǎn)HDMI芯片一側(cè)則需要PCLK、DE、HSYNC、VSYNC和RGB數(shù)據(jù)線。我當時的引腳分配參考如下注意不同芯片接口有差異但整體思路一致信號方向電平建議MCLK輸出到攝像頭3.3V由PLL輸出24MHzPCLK輸入從攝像頭1.8V/3.3V視模組而定串33ΩVSYNC/HREF輸入從攝像頭同PCLK與數(shù)據(jù)線同BankD[7:0]輸入從攝像頭同PCLK同一Bank盡量緊湊SIO_C/SIO_D雙向3.3V必須接上拉電阻2.2kΩ~4.7kΩHDMI_PCLK輸出到HDMI芯片3.3VPLL輸出75MHz或74.25MHzHDMI_DE/HS/VS輸出到HDMI芯片3.3V顯示時序模塊產(chǎn)生HDMI_RGB[15:0]輸出到HDMI芯片3.3V位寬按芯片支持選引腳分配的原則攝像頭的一組信號盡量放在同一個Bank避免跨Bank帶來的電平標準沖突PCLK這種高速時鐘輸入要挑靠近PLL的引腳I2C時鐘和數(shù)據(jù)不要在板子上繞太遠。2.2 時鐘與復位策略OV5640需要一個主時鐘MCLK典型值24MHz可以由外部晶振直接給也可以由FPGA PLL分頻產(chǎn)生。用PLL的好處是可以完全由軟件控制。如果板上只有50MHz晶振PLL配置成M/N12/25就能得到24MHz。顯示側(cè)如果走RGB轉(zhuǎn)HDMI芯片需要給一個像素時鐘。720p60標準是74.25MHz這個頻率用整數(shù)分頻不好從50MHz得到最理想的方案是板上帶27MHz晶振PLL倍頻到74.25MHz27×11/4。如果沒有27MHz晶振用50MHz生成75MHz也可以因為75MHz只是多了約1%很多顯示器能正常識別只是不符合標準。如果做720p顯示時序參數(shù)按75MHz重新算一遍即可。復位策略要分兩級。第一級是系統(tǒng)上電復位把PLL鎖定、把各模塊狀態(tài)機置初值。第二級是在PLL鎖定后給攝像頭一個上電復位時序拉低RESET一段時間釋放再延時至少20ms才開始SCCB配置。這個延時別省很多花屏問題就是配置前攝像頭沒徹底復位導致的。2.3 電源與硬件上的幾個坑OV5640模組的IO電平要特別注意。有的模組DVP信號電平是1.8V有的是2.8V拉到FPGA的3.3V Bank上就可能超壓。穩(wěn)妥的做法是串33Ω或100Ω電阻做隔離或者查清楚模組手冊再決定Bank電壓。如果模組自帶電平轉(zhuǎn)換那就放心接。HDMI發(fā)送芯片的電源一般有1.8V和3.3V兩路去耦電容要盡量靠近電源引腳每路至少一個10μF鉭電容加幾個0.1μF陶瓷電容。TMDS差分線如果在自制PCB上必須做100Ω差分阻抗控制等長走線如果是在開發(fā)板上用杜邦線飛線到HDMI芯片轉(zhuǎn)接板那就別指望太高分辨率了640×480一般還穩(wěn)720p就開始碰運氣。另一個容易忽略的問題HDMI的5V電源和HPD檢測。HDMI座子的5V腳要接電源HPDHot Plug Detect要拉高不然顯示器根本不會識別到信號源。有些轉(zhuǎn)接板會把這部分電路做完但如果自己畫板一定檢查HPD的上下拉配置。3. Verilog核心模塊實現(xiàn)從SCCB配置到HDMI時序3.1 SCCB/I2C配置模塊OV5640的全部秘密在這OV5640的寄存器配置是通過SCCB總線完成的SCCB基本兼容I2C寫時序幾乎一樣。從地址一般是0x3C寫/0x3D讀有些模組是0x21具體看模組原理圖。這部分是整個項目最“磨人”的地方因為OV5640要配的寄存器有好幾百個配錯一個就可能導致黑屏、花屏、顏色不對。模塊設計分兩層底層是一個通用的I2C主機驅(qū)動支持起始條件、停止條件、逐字節(jié)發(fā)送、ACK檢測上層是一個初始化狀態(tài)機從ROM或常量表里逐條取出寄存器地址和值調(diào)用底層驅(qū)動寫入。I2C驅(qū)動核心就是把握好SCL/SCK的時序用計數(shù)器產(chǎn)生符合時鐘頻率的時序。SCL頻率建議用100kHz低速穩(wěn)定別追求400kHz。下面是一個寫字節(jié)狀態(tài)機的核心框架// I2C寫一個字節(jié)返回ack信號 // 狀態(tài)IDLE - START - SHIFT8 - ACK - STOP always (posedge clk_i2c or negedge rst_n) begin if (!rst_n) begin state IDLE; end else begin case (state) IDLE: if (start_req) begin scl 1b0; // 準備發(fā)起起始 state START; end START: begin sda_out 1b0; // 起始條件SCL高時SDA拉低 state SHIFT8; end SHIFT8: begin // 每個bit先SDA賦值再SCL拉高再拉低 // 用bit_cnt控制8個bit end ACK: state STOP; STOP: state IDLE; endcase end end注意一點寫OV5640寄存器時每個寄存器寫完后最好加1ms左右延時等內(nèi)部生效。尤其PLL、分辨率相關(guān)的寄存器改完不能馬上接著寫下一個否則配置容易丟。初始化寄存器表網(wǎng)上有很多公開模板可以直接搜索“OV5640 register init value”或者參考OV5640的驅(qū)動源碼。關(guān)鍵配置項包括輸出分辨率0x3800~0x3814區(qū)間的時序參數(shù)、輸出格式0x4300設為0x6F對應RGB565、0x60對應RGB888、PLL分頻0x3035/0x3036/0x3037、鏡像翻轉(zhuǎn)0x3820/0x3821、自動曝光和自動白平衡開關(guān)0x3212等。別自己憑感覺改對照datasheet的寄存器map逐個核對。3.2 DVP采集模塊VSYNC、HREF、PCLK三個信號怎么配合OV5640的DVP接口有三個關(guān)鍵信號VSYNC是幀同步一幀開始和結(jié)束的標志HREF是行有效高電平期間每個PCLK上升沿對應一個有效數(shù)據(jù)字節(jié)PCLK是像素時鐘采樣邊沿一般是上升沿。采集模塊的Verilog邏輯其實不復雜難點在于處理RGB565的字節(jié)拼接。OV5640在RGB565輸出模式下一個像素16bit分兩個PCLK周期輸出每個周期8bit。默認順序通常是先高字節(jié)后低字節(jié)但具體順序取決于寄存器配置。// 采集模塊核心邏輯偽代碼 // 兩級觸發(fā)器打拍同步避免亞穩(wěn)態(tài) reg vsync_d1, vsync_d2; reg href_d1, href_d2; reg pclk_d1, pclk_d2; always (posedge clk) begin vsync_d1 vsync; vsync_d2 vsync_d1; href_d1 href; href_d2 href_d1; pclk_d1 pclk; pclk_d2 pclk_d1; end // PCLK上升沿采樣數(shù)據(jù) always (posedge pclk_d2 or negedge rst_n) begin if (!rst_n) begin byte_cnt 2d0; rgb_data 16d0; end else if (href_d2) begin case (byte_cnt) 2d0: begin rgb_data[15:8] din; byte_cnt 2d1; end 2d1: begin rgb_data[7:0] din; // 一個像素湊齊可以寫入FIFO fifo_wr_data {rgb_data[15:8], din}; fifo_wr_req 1b1; byte_cnt 2d0; end endcase end else begin byte_cnt 2d0; fifo_wr_req 1b0; end end這里有個很常見的坑data是8位還是10位。OV5640有10根數(shù)據(jù)線D[9:0]如果只用RGB565通常取D[9:2]作為8位數(shù)據(jù)但不同模組/配置可能不同要在實際調(diào)試時用邏輯分析儀確認一下。如果發(fā)現(xiàn)圖像顏色間隔出現(xiàn)“很規(guī)律的雜點”優(yōu)先懷疑數(shù)據(jù)位取錯或字節(jié)順序反了。VSYNC的作用是同步幀的啟停一般用下降沿開始計數(shù)在下一幀VSYNC前完成一行行采集。用ILA或者板載LED把VSYNC和HREF引出來觀察是很有用的調(diào)試手段。3.3 跨時鐘域與行緩存FIFO深度怎么算攝像頭輸出的PCLK和顯示器側(cè)的像素時鐘不是同一個域兩者頻率和相位都不同步直接用組合邏輯互相采必然出現(xiàn)亞穩(wěn)態(tài)和花屏。正確做法是異步FIFO隔離。FIFO的寫時鐘是PCLK讀時鐘是顯示像素時鐘數(shù)據(jù)寬度16bit深度要按“一行像素數(shù)裕量”來算。以720p為例一行1280像素每像素16bit理論上深度2048就夠存一行。但考慮到FIFO讀寫同時進行讀側(cè)可能有突發(fā)延遲建議深度取4096。EP4CE10內(nèi)部RAM只有414Kbit4096×16只有64Kbit完全放得下。// Quartus/Altera FIFO IP核例化 fifo_16x4096 u_fifo ( .wrclk(pclk_d2), // 寫時鐘來自攝像頭 .wrreq(fifo_wr_req), // HREF有效期間像素寫入請求 .data({hi_byte, lo_byte}), // 16bit RGB565 .rdclk(pixel_clk), // 讀時鐘來自顯示時序PLL .rdreq(fifo_rd_req), // DE有效時請求讀取 .q(display_rgb), // 讀出的像素數(shù)據(jù) .wrfull(), .rdempty(rd_empty) );讀側(cè)的控制邏輯比較簡單顯示時序模塊在DE高電平期間每個像素時鐘讀一次FIFO讀到的數(shù)據(jù)直接送去HDMI芯片。但要注意FIFO空標志如果DE期間讀空了就直接輸出黑色像素0x0000避免數(shù)據(jù)錯位。這個方案的局限在于沒有真正的幀同步。寫側(cè)跟著攝像頭的VSYNC節(jié)奏讀側(cè)跟著顯示器時序兩者互相獨立可能出現(xiàn)“寫到一半被讀走”的情況畫面在某一幀會有一條水平的撕裂線。解決撕裂的辦法一般有用雙口RAM做兩行乒乓緩存或者干脆外掛SDRAM做多幀緩存。入門階段先接受這個缺陷重點是把圖像穩(wěn)定顯示出來。3.4 顯示時序與HDMI發(fā)送從DE到TMDS顯示時序生成是FPGA里最經(jīng)典的“數(shù)數(shù)”模塊沒有技術(shù)難點只有細心。以720p60為例標準時序參數(shù)如下參數(shù)值像素時鐘74.25MHz水平有效1280H前臺HFP110水平同步HSYNC40H后臺HBP220水平總數(shù)1650垂直有效720V前臺VFP5垂直同步VSYNC5V后臺VBP20垂直總數(shù)750用兩個計數(shù)器分別數(shù)行和場在有效區(qū)域內(nèi)拉高DE輸出RGB數(shù)據(jù)在同步區(qū)間輸出對應的HSYNC/VSYNC電平代碼不復雜。// 行同步計數(shù)器示例 reg [10:0] h_cnt; reg [9:0] v_cnt; always (posedge pixel_clk or negedge rst_n) begin if (!rst_n) begin h_cnt 0; end else if (h_cnt H_TOTAL - 1) begin h_cnt 0; end else begin h_cnt h_cnt 1b1; end end assign hsync (h_cnt H_SYNC_START) (h_cnt H_SYNC_END); assign de (h_cnt H_ACTIVE_START) (h_cnt H_ACTIVE_END) (v_cnt V_ACTIVE_START) (v_cnt V_ACTIVE_END);如果用的是RGB轉(zhuǎn)HDMI芯片F(xiàn)PGA這邊的工作到這里就結(jié)束了直接把DE、HSYNC、VSYNC、RGB數(shù)據(jù)、PCLK接給芯片即可。芯片內(nèi)部會編碼成TMDS并串行輸出。如果是自己編碼TMDS需要實現(xiàn)DVI的編碼器每個通道把8bit數(shù)據(jù)經(jīng)過編碼變成10bit三個通道分別處理R、G、B再加上一個時鐘通道。編碼規(guī)則不復雜基于異或/異或非維護DC平衡但寫起來代碼量大而且需要把數(shù)據(jù)按10bit并行寬度經(jīng)OSERDES或DDR輸出寄存器轉(zhuǎn)成串行。EP4CE10沒有專門的OSERDES一般用兩個寄存器配合IO clock實現(xiàn)DDR輸出。這個方案我建議作為進階挑戰(zhàn)別和主線混在一起做。4. 調(diào)試實錄與常見問題排查4.1 上電黑屏九成問題出在這三處拿到板子第一次上電顯示器沒畫面這是必然的別慌。按順序排查三處攝像頭有沒有正常工作、SCCB配置有沒有成功、HDMI側(cè)有沒有被識別。第一攝像頭是否工作。用示波器或邏輯分析儀看PCLK引腳有沒有波形正常配置后PCLK應該有穩(wěn)定的時鐘輸出。如果PCLK沒有波形檢查MCLK有沒有送到RESET和PWDN的電平對不對。很多OV5640模組的PWDN引腳要拉低才工作拉高是掉電模式這個特別容易踩。第二SCCB配置是否成功。把FPGA的I2C驅(qū)動中每個寫操作的ACK信號引出來如果連續(xù)出現(xiàn)NACK說明從機地址不對或者物理連接有問題。我曾遇到一個模組寫地址是0x21而不是0x3C結(jié)果怎么配都沒反應。物理層方面SIO_D要接上拉電阻有些模組自帶上拉有些沒有需要自己補否則時鐘根本沒波形。第三HDMI是否被識別。用顯示器切換輸入源如果能看到“無信號”變成“信號輸入中”甚至花屏變綠說明HDMI鏈路已經(jīng)建立問題在數(shù)據(jù)端如果始終無信號檢查HPD引腳是否拉高、5V是否正常、TMDS時鐘通道有沒有輸出。這是黑屏問題里最容易混淆的一環(huán)很多人糾結(jié)半天攝像頭結(jié)果其實是HDMI芯片的電平配置不對。4.2 花屏、錯位、撕裂的排查順序畫面已經(jīng)有了但“不對”這類問題比黑屏好定位得多通常是下面幾個原因。顏色偏色、整體發(fā)綠發(fā)紫先查RGB數(shù)據(jù)位接錯或者字節(jié)順序拼反。比如RGB565的低字節(jié)和高字節(jié)交換圖像整體色調(diào)就會偏移。再查輸出格式寄存器是否真的配成了RGB565如果攝像頭實際輸出YUV422但按RGB565解讀顏色就會明顯不對。圖像錯位、斜切面多半是行場同步時序參數(shù)和實際輸出分辨率不匹配。把顯示時序的H_TOTAL、V_TOTAL和有效區(qū)間參數(shù)逐項核對特別是HFP/HBP是否是0。HDMI芯片對各個時序區(qū)間有一定容錯但DE與HSYNC的相對位置不對畫面就會沿對角線撕裂。橫向撕裂這是行緩存方案固有的問題攝像頭VSYNC和顯示器VSYNC不同步。想徹底消除只能上SDRAM幀緩存。臨時緩解辦法是降低幀率比如把攝像頭輸出調(diào)到30fps以下撕裂會不那么明顯。整屏雪花一般是TMDS數(shù)據(jù)鏈路問題。如果用轉(zhuǎn)接芯片查PCLK是否干凈、復位是否穩(wěn)定、RGB數(shù)據(jù)位寬和芯片配置是否一致。如果自己編碼TMDS優(yōu)先懷疑輸出IO沒有正確約束為差分標準或者時鐘通道沒有輸出。4.3 Quartus II實操細節(jié)Pin Planner與時序約束工程跑不通很多不是邏輯問題而是工程配置問題。幾個高頻坑點Pin Planner里必須把攝像頭的PCLK、FIFO讀時鐘、HDMI像素時鐘明確分配在可用的全局時鐘引腳或PLL輸入/輸出專用引腳上否則綜合時會報錯或者時序收斂不了。添加時序約束是必須的。至少在Synopsys Design Constraints里寫create_clock -name clk_in -period 20.000 [get_ports {clk}] create_clock -name pclk -period 20.833 [get_ports {pclk}]PCLK來自攝像頭不是FPGA內(nèi)部時鐘但Quartus也需要知道它的周期才能對跨時鐘域FIFO的路徑做分析。如果你用SignalTap做在線調(diào)試探針信號不要跨太多時鐘域否則采樣數(shù)據(jù)亂飛很難分辨是邏輯錯還是采樣錯。還有一點Cyclone IV的PLL配置界面里M/N設置完之后看實際輸出頻率和相位確認沒有超規(guī)格。MCLK給24MHz時最好用“時鐘使能”方式去做而不是拿一個高速PLL輸出直接當MCLK否則攝像頭輸入時鐘毛刺會很重。4.4 經(jīng)驗清單一次跑通的關(guān)鍵習慣項目做了幾輪之后我總結(jié)出幾個值得養(yǎng)成的習慣照做能省掉大量反復折騰的時間。先跑測試彩條再接攝像頭。把顯示時序模塊獨立驗證一下用FPGA內(nèi)部產(chǎn)生彩條數(shù)據(jù)填到RGB輸出如果顯示器能顯示彩條說明HDMI鏈路和顯示時序沒問題問題范圍就縮小到采集側(cè)。這個步驟特別重要能直接把你從“全鏈路黑屏”里解放出來。攝像頭配置分階段驗證。不要一次性寫入幾百條寄存器先把I2C驅(qū)動跑通然后只寫基礎配置輸出格式、分辨率、時鐘看能不能出動態(tài)畫面再逐步加AWB、曝光、飽和度等寄存器。這樣出了問題能快速定位是哪一組配置引起的。善用邏輯分析儀。如果板子沒有預留測試點可以用SignalTap把VSYNC、HREF、PCLK、FIFO寫請求、讀請求這些內(nèi)部信號引出來截圖保存。肉眼對著波形看比猜有效得多。我曾經(jīng)因為FIFO的rdreq信號在DE期間偶爾沒拉高導致一行像素缺了十幾個點看著就是一條細豎線要不是看波形根本找不到。對EP4CE10這種資源緊張的芯片編譯設置上把優(yōu)化策略改成Area也能省不少資源。不過別過度優(yōu)化如果邏輯都快放不下了優(yōu)先考慮簡化設計比如把RGB888改成RGB565或者降低分辨率。做完這個項目之后我對“攝像頭采集HDMI顯示”這類系統(tǒng)心里就有底了再去看算法加速、目標檢測這些進階方向至少不會被數(shù)據(jù)通路卡住。我的建議是不要急著加各種圖像處理算法先把這條通路跑到穩(wěn)定真正理解每個信號為什么存在、每個時序為什么這么定然后再去玩濾波、邊緣檢測、灰度轉(zhuǎn)換你會突然發(fā)現(xiàn)那些算法其實都不難。本文還有配套的精品資源點擊獲取