1. 程式人生 > >基於FPGA的VGA顯示靜態圖片

基於FPGA的VGA顯示靜態圖片

activit right 什麽 業界 intel 後來 像素點 處理 打開

  終於熬到暑假了,記過三四周的突擊帶考試,終於為我的大二畫上了一個完整的句號,接下來終於可以靜心去做自己想做的事情了,前一陣子報了一個線上培訓班,學學Sobel邊緣檢測,之前一直在學習圖像處理,但是因為一直看人家的代碼,到後來難免有點空虛。所以說自己狠下心來,報了一個線上培訓班,重新學習一下,自己設計Sobel邊緣檢測,勢要擺脫抄別人代碼的魔咒。所以這次圖像顯示部分和在彩色條紋中顯示一副圖片的代碼,全部是我自己設計的,雖然不是什麽大工程,但是還是滿滿的成就感,這次用的時間比較久,因為使用的是新板子,Xilinx的ZYBO,之前沒用過,一直放在實驗室裏吃灰,所以不如把它用起來,想起來要學的東西還是很多的,慢慢學唄。

ZYNQ算是Xilinx的一款比較高端的板子了,上面有以太網接口、USB2.0/OTG、HDMI雙向接口,SD卡槽,而且板子內部還嵌入了ARM,上面可以跑linux,價格也不菲。剛開始查了一下手冊了解到板子晶振是50Mhz,然後試了半天就是沒有把VGA驅動起來,後來在仔細查了一下手冊,這款板子在某種情況下板子提供的是125Mhz引腳為L16,然而我不知道怎麽用50Mhz,那就直接用125Mhz吧。前面沒寫過關於VGA的博客,這次就順帶寫一下吧。

VGA顯示其實就是兩條線,一個是行掃描,一個是場掃描,在行有效和場有效的時候把數據發送給VGA即可顯示[email protected]

/* */,[email protected],即行為640個像素,場為480個像素。

顯示器掃描方式分為逐行掃描和隔行掃描:逐行掃描是掃描從屏幕左上角一點開始,從左像右逐點掃描,每掃描完一行,電子束回到屏幕的左邊下一行的起始位置,在這期間,CRT對電子束進行消隱,每行結束時,用行同步信號進行同步;當掃描完所有的行,形成一幀,用場同步信號進行場同步,並使掃描回到屏幕左上方,同時進行場消隱,開始下一幀。隔行掃描是指電子束掃描時每隔一行掃一線,完成一屏後在返回來掃描剩下的線,隔行掃描的顯示器閃爍的厲害,會讓使用者的眼睛疲勞。

技術分享

圖 – VGA屏幕掃描原理

行消隱(HBlank)在將光信號轉換為電信號的掃描過程中,掃描總是從圖像的左上角開始,水平向前行進,同時掃描點也以較慢的速率向下移動。當掃描點到達圖像右側邊緣時,掃描點快速返回左側,重新開始在第1行的起點下面進行第2行掃描,行與行之間的返回過程稱為水平消隱。一幅完整的圖像掃描信號,由水平消隱間隔分開的行信號序列構成,稱為一幀。掃描點掃描完一幀後,要從圖像的右下角返回到圖像的左上角,開始新一幀的掃描,這一時間間隔,叫做垂直消隱,也稱場消隱(VBlank)。我們稱行同步、場同步。

行場消隱信號:是針對老式顯像管的成像掃描電路而言的。電子槍所發出的電子束從屏幕的左上角開始向右掃描,一行掃完需將電子束從右邊移回到左邊以便掃描第二行。在移動期間就必須有一個信號加到電路上,使得電子束不能發出。不然這個回掃線會破壞屏幕圖像的。這個阻止回掃線產生的信號就叫作消隱信號,場信號的消隱也是一個道理。

技術分享

圖 – 行掃描

技術分享

圖 – 場掃描

技術分享

圖 – VGA掃描時序

如上圖的掃描參數已經有官方的標準了,這裏我就不再做記錄了,到時直接用就可以了。

[email protected],ZYBO的板子晶振是125Mhz,所以首先要先進行分頻,我這裏直接用Vivado調用PLL。還沒有過用Vivado調用PLL的博客,現在總結一下吧,以防後面忘記。技術分享

點擊IP catalog進行IP設置技術分享

為了快速找到想要的IP,在右上角直接搜索Clocking,然後就會出現如圖所示界面,雙擊clocking wizard,進行PLL的配置技術分享

彈出如圖所示界面後,一次按上圖進行配置,在component name中寫下IP的名字,把show disabled ports勾選為空,在primitive中選擇MMCM,在input clock information中選擇輸入時鐘。這裏的MMCM我查了一下就是他包含了PLL,所以我們直接選擇MMCM。但是有時候如果選擇PLL也會出現錯誤,所以一般首選MMCM。技術分享

這裏設置輸出時鐘,還可以設置相位和占空比。技術分享

選擇復位為低電平觸發、選擇locked

技術分享

這裏可以自定義端口名

技術分享

技術分享

點擊OK,Generate,即可生成PLL IP Core技術分享

點擊IP source、找到後綴為.veo的文件,雙擊打開技術分享

裏面的內容就是可以直接實例化調用的端口生成。

這樣便完成了VGA驅動時鐘的生成,這裏我把其他幾種顯示格式的參數和RGB顯示的參數貼出來,這樣便省去了不少事情。然後就是把你要顯示的數據在行掃描有效和場掃描有效的時候輸出,即可在顯示屏顯示了。其實這個顯示並不難,那我為什麽要專門寫篇博客記錄呢?因為以前老是看別人的代碼,看的多了,自己的能力還是沒有多大提升,但這部分顯示圖片是完全我自己分析時序顯示出來的,所以有很大的成就感。學習這個東西還是得有人教導,從我學習FPGA以來,都是自己一個人瞎琢麽,學習了一年了還沒有一個好的畫時序圖的習慣,到仿真的時候再湊出時序圖,還是要從基礎抓起,不能只會敲代碼。時序設計是關鍵,設計思想必須有。

要顯示一個彩色條紋也是比較簡單的,例如在前一百五十行給VGA的數據為白色的,中間180行給VGA的數據為綠色,後面相同的方法。我這裏要做的實驗是在顯示屏的左上角開一個200x200的框,最後將一幅200x200的圖片顯示進去,首先開一個200x200的正方形框,實現的方法就是控制行有效計數器計到需要顯示正方形框的時候紫色的數據給lcd_data,行計數器為0-200,其他情況還是前面顯示條紋的數據,同樣的場有效計數器也從0-200計數時顯示紫色數據帶lcd_data,這樣就會在顯示屏左上角形成一個正方形的框。如下圖所示。技術分享

要顯示一張圖片到VGA就需要調用IP Core,我這裏需要調用一個單口RAM IP,使用軟件將圖片生成十六進制的數據,可以用MATLAB,我這裏推薦一款軟件,是一個業界名人自己寫的十分好用,如下圖所示,只需要將圖片加載進去,就可以生成你想要的圖像數據格式了,這裏要註意生成的圖像數據RGB的位寬,一定要和你板子的VGA位寬一致,否則顯示不出來的。

技術分享

技術分享

  使用這個軟件轉化之前,除了閱讀板子手冊看你的板子RAM的容量能裝下多大的圖像數據,需要找一張合適的圖片,這裏小提示一下,可以用windows自帶的畫圖軟件將圖片打開,右鍵重新調整大小去掉保持縱橫比,選擇像素,這樣就可以任意修改圖像大小了!RAM配置可參考我前面的相關博文:基於Vivado調用ROM IP core設計DDS

註:Xilinx是.coe文件、Intel (Altera)是.mif文件,這兩種文件只是格式不同但本質上是一樣的。

技術分享

  RAM/ROM讀取有延時,要在掃描第一個點的前兩個時鐘周期讀取RAM/ROM,我這裏用的是雙口RAM,在Vivado這裏顯示的是有兩個時鐘的周期的延時,也就是當你給讀命令時,RAM會把讀出來的數據緩存兩級在才會輸出給你想給數據的地方。技術分享

  我這裏遺留一個問題,在學習開源騷客的教程的時候,上面說的需要提前兩個時鐘周期給RAM地址,這樣出來的數據才能同步,我試了好久都沒有成功,在這個問題上浪費的時間太長了,後面有機會再去解決吧。我要進行下面的課程學習了。我認為RAM數據出來的端口是一直有數據的,而且我最終顯示出來的靜態圖片也是完整的,沒有觀察到像素點的缺失,所以這裏這個問題保留,後面我在學習的過程中再想辦法把它搞清楚解決掉。

  這次的基於FPGA的圖像顯示部分代碼,完全是我自主設計,雖然不是很高的技術含量,但是總算擺脫了抄別人代碼的魔咒了,最後所有工作都做好後,下載板子就會呈現下面這一幅圖的樣子,這樣看來顯示效果還挺不錯的呢!技術分享

技術分享

轉載請註明出處:NingHeChuan(寧河川)

個人微信訂閱號:NingHeChuan

如果你想及時收到個人撰寫的博文推送,可以掃描左邊二維碼(或者長按識別二維碼)關註個人微信訂閱號

知乎ID:NingHeChuan

微博ID:NingHeChuan

原文地址:http://www.cnblogs.com/ninghechuan/p/7260383.html

基於FPGA的VGA顯示靜態圖片