基於FPGA的5寸LCD顯示屏的顯示控制


基於FPGA 5 LCD 顯示屏的顯示控制
作者:lee
1, 圖像處理基礎知識
數字圖像處理是指將圖像信號轉換成數字信號並利用計算機對其進行處理的過程。圖像處理最早出現於 20  世紀  50  年代,當時的電子計算機已經發展到一定水平,人們開始利用計算機來處理圖形和圖像信息。數字圖像處理作為一門學科大約形成於  20  世紀  60  年代初期。早期的圖像處理的目的是改善圖像的質量,它以人為對象,以改善人的視覺效果為目的。圖像處理中,輸入的是質量低的圖像,輸出的是改善質量后的圖像,常用的圖像處理方法有圖像增強、復原、編碼、壓縮等。
數字圖像處理常用方法:
)圖像變換:由於圖像陣列很大,直接在空間域中進行處理,涉及計算量很大。因此,往往采用各種圖像變換的方法,如傅立葉變換、沃爾什變換、離散余弦變換等間接處理技術,將空間域的處理轉換為變換域處理,不僅可減少計算量,而且可獲得更有效的處理(如傅立葉變換可在頻域中進行數字濾波處理)。目前新興研究的小波變換在時域和頻域中都具有良好的局部化特性,它在圖像處理中也有着廣泛而有效的應用。
)圖像編碼壓縮:圖像編碼壓縮技術可減少描述圖像的數據量(即比特數),以便節省圖像傳輸、處理時間和減少所占用的存儲器容量。壓縮可以在不失真的前提下獲得,也可以在允許的失真條件下進行。編碼是壓縮技術中最重要的方法,它在圖像處理技術中是發展最早且比較成熟的技術。
)圖像增強和復原:圖像增強和復原的目的是為了提高圖像的質量,如去除噪聲,提高圖像的清晰度等。圖像增強不考慮圖像降質的原因,突出圖像中所感興趣的部分。如強化圖像高頻分量,可使圖像中物體輪廓清晰,細節明顯;如強化低頻分量可減少圖像中噪聲影響。圖像復原要求對圖像降質的原因有一定的了解,一般講應根據降質過程建立“降質模型”,再采用某種濾波方法,恢復或重建原來的圖像。
)圖像分割:圖像分割是數字圖像處理中的關鍵技術之一。圖像分割是將圖像中有意義的特征部分提取出來,其有意義的特征有圖像中的邊緣、區域等,這是進一步進行圖像識別、分析和理解的基礎。雖然目前已研究出不少邊緣提取、區域分割的方法,但還沒有一種普遍適用於各種圖像的有效方法。因此,對圖像分割的研究還在不斷深入之中,是目前圖像處理中研究的熱點之一。
)圖像描述:圖像描述是圖像識別和理解的必要前提。作為最簡單的二值圖像可采用其幾何特性描述物體的特性,一般圖像的描述方法采用二維形狀描述,它有邊界描述和區域描述兩類方法。對於特殊的紋理圖像可采用二維紋理特征描述。隨着圖像處理研究的深入發展,已經開始進行三維物體描述的研究,提出了體積描述、表面描述、廣義圓柱體描述等方法。
)圖像分類(識別):圖像分類(識別)屬於模式識別的范疇,其主要內容是圖像經過某些預處理(增強、復原、壓縮)后,進行圖像分割和特征提取,從而進行判決分類。圖像分類常采用經典的模式識別方法,有統計模式分類和句法(結構)模式分類,近年來新發展起來的模糊模式識別和人工神經網絡模式分類在圖像識別中也越來越受到重視。
隨着計算機技術的發展,圖像處理技術已經深入到我們生活中的方方面面,其中,在娛樂休閑上的應用已經深入人心。圖像處理技術在娛樂中的應用主要包括:電影特效制作、電腦電子游戲、數碼相機、視頻播放、數字電視等。
電影特效制作:自從 20  世紀  60  年代以來,隨着電影中逐漸運用了計算機技術,一個全新的電影世界展現在人們面前,這也是一次電影的革命。越來越多的計算機制作的圖像被運用到了電影作品的制作中。其視覺效果的魅力有時已經大大超過了電影故事的本身。如今,我們已經很難發現在一部電影中沒有任何的計算機數碼元素。
電腦電子游戲:電腦電子游戲的畫面,是近年來電子游戲發展最快的部分之一。從 1996  年到現在,游戲畫面的進步簡直可以用突飛猛進來形容,隨着圖像處理技術的發展,眾多在幾年前無法想象的畫面在今天已經成為了平平常常的東西。
數碼相機:所謂數碼相機,是一種能夠進行拍攝,並通過內部處理把拍攝到的景物轉換成以數字格式存放圖像的特殊照相機。與普通相機不同,數碼相機並不使用膠片,而是使用固定的或者是可拆卸的半導體存儲器來保存獲取的圖像。數碼相機可以直接連接到計算機、電視機或者打印機上。在一定條件下,數碼相機還可以直接接到移動式電話機或者手持 PC  機上。由於圖像是內部處理的,所以使用者可以馬上檢查圖像是否正確,而且可以立刻打印出來或是通過電子郵件傳送出去。
視頻播放與數字電視:家庭影院中的 VCD  ,  DVD  播放器和數字電視中,大量使用了視頻編碼解碼等圖像處理技術,而視頻編碼解碼等圖像處理技術的發展,也推動了視頻播放與數字電視象高清晰,高畫質發展。
2,LCD 顯示的基本原理
   <ignore_js_op>
1 VGA 的顯示時序
如圖1 所示, LCD 的顯示和 VGA 的顯示時序基本一致,都是從屏幕的左上角開始(從左往右,從上往下)經過 Hor_sync_time H_back_porch 時間,屏幕開始顯示,到 H_front_porch 時間后結束一行的顯示,然后回到下一行左側,循環到屏幕的最后一行掃描。在豎直方向上,經過  ver_sync_time v_back_porch 時間豎直方向屏幕開始顯示,到 ver_front_porch 豎直方向顯示結束。一幀顯示完成。
當屏幕的刷新頻率快於人眼的視覺感知的頻率我們將看不出屏幕的閃爍效果。
3,FPGA 實現
本實驗目的:
   本節目的是讓大家了解LCD 屏的顯示原理,以及為后期我們的 FPGA 的數字圖像處理打下基礎。
模塊划分:
<ignore_js_op>
2 TFT5 寸顯示屏顯示 FPGA 模塊結構
 
<ignore_js_op>
綜合后 FPGA 的內部模塊以及接口
從圖2 和圖 3 可知, LCD 屏顯示控制有 Key_filter rgb_gen 以及 TFT_CTRL_800_480_16bit 三大模塊組成。 Key_filter 完成按鍵的消抖, rgb_gen 完成屏幕顯示的控制, TFT_CTRL_800_480_16bit 模塊完成 TFT5 寸屏幕的驅動。
本實驗通過按鍵來完成對屏幕顏色輸出的控制。
RGB565 可以完成 65536 種顏色的輸出。
硬件平台:
TFT5 寸屏幕 / VGA 顯示屏
FPGA 開發板
FPGA 源碼:
Rgb_gen  模塊源碼
  /*
Module name:   rgb_gen.v
Description:  
              
Data:          2018/01/25
Engineer:      
e-mail:         137194782@qq.com
微信公眾號:  FPGA 開源工作室
QQ 資料群:     664712733
*/
`timescale 1ns/1ps
module rgb_gen(
       input clk,
                 input rst_n,
                 input [3:0] key_cnt,
                 
                 output reg [15:0] rgb_data,
                 input  [11:0] hcount,
       input  [11:0] vcount
       );
        parameter TFT_HS_end=10'd1,
                                 hdat_begin=10'd46,
                                 hdat_end=10'd846,
                                 hpixel_end=12'd1056,
                                 TFT_VS_end=10'd1,
                                 vdat_begin=10'd24,
                                 vdat_end=10'd504,
                                 vline_end=10'd524;
        parameter h_8 = 10'd100;
        parameter v_8 = 10'd60;
always @(posedge clk or negedge rst_n) begin
  if(!rst_n)
    rgb_data <= 16'h0000;
  else
    case(key_cnt)
      4'd0:rgb_data <= 16'hf800;    //red
                4'd1:rgb_data <= 16'h07e0;  //green
                4'd2:rgb_data <= 16'h001f;  //blue
                4'd3:rgb_data <= 16'hf81f;  //purple
                4'd4:rgb_data <= 16'hffe0;  //yellow
                4'd5:rgb_data <= 16'h07ff;  //cyan
                4'd6:rgb_data <= 16'hfc00;  //orange
                4'd7:rgb_data <= 16'hffff;   //white
                4'd8:rgb_data <= 16'h0000;  //black
                4'd9:begin
                  if((hcount[3] == 1'b1) ^ (vcount[3] == 1'b1))
                    rgb_data <= 16'hffff;
                  else
                    rgb_data <= 16'h0000;               //Lattices image 1
                end
                4'd10:begin
                  if((hcount[6] == 1'b1) ^ (vcount[6] == 1'b1))
                    rgb_data <= 16'hffff;
                  else
                    rgb_data <= 16'h0000;               //Lattices image 2
                end
                4'd11:begin
                  if(hcount == hdat_begin)
                    rgb_data <= 16'hf800;
                  else if(hcount == hdat_begin + h_8)
                    rgb_data <= 16'h07e0;
                  else if(hcount == hdat_begin + h_8*2)
                    rgb_data <= 16'h001f;
                  else if(hcount == hdat_begin + h_8*3)
                    rgb_data <= 16'hf81f;
                  else if(hcount == hdat_begin + h_8*4)
                    rgb_data <= 16'hffe0;
                  else if(hcount == hdat_begin + h_8*5)
                    rgb_data <= 16'h07ff;
                  else if(hcount == hdat_begin + h_8*6)  //color bar h
                    rgb_data <= 16'hfc00;
                  else if(hcount == hdat_begin + h_8*7)
                    rgb_data <= 16'hffff;
                  else
                    rgb_data <= rgb_data;
                end
                4'd12:begin
                  if(vcount == vdat_begin)
                    rgb_data <= 16'hf800;
                  else if(vcount == vdat_begin + v_8)
                    rgb_data <= 16'h07e0;
                  else if(vcount == vdat_begin + v_8*2)
                    rgb_data <= 16'h001f;
                  else if(vcount == vdat_begin + v_8*3)
                    rgb_data <= 16'hf81f;
                  else if(vcount == vdat_begin + v_8*4) //color bar v
                    rgb_data <= 16'hffe0;
                  else if(vcount == vdat_begin + v_8*5)
                    rgb_data <= 16'h07ff;
                  else if(vcount == vdat_begin + v_8*6)
                    rgb_data <= 16'hfc00;
                  else if(vcount == vdat_begin + v_8*7)
                    rgb_data <= 16'hffff;
                  else
                    rgb_data <= rgb_data;
                end
                4'd13:begin
                   rgb_data <= {5'b0,vcount[8:3],5'b0};  //Horizontal green gradual change
                end
                4'd14:begin
                   rgb_data <= {vcount[8:4],vcount[8:3],vcount[8:4]}; //vertical gray Gradient
                end
                4'd15:begin
                   rgb_data <= {hcount[8:4],11'b0};  //Horizontal red gradual change
                end
         endcase
end
 
endmodule
 
TFT_CTRL_800_480_16bit 模塊源碼:
module TFT_CTRL_800_480_16bit(
        Clk33M,        // 系統輸入時鍾 33MHZ
        Rst_n,        // 復位輸入,低電平復位
        data_in,        // 待顯示數據
        hcount,                //TFT 行掃描計數器
        vcount,                //TFT 場掃描計數器
        TFT_RGB,        //TFT 數據輸出
        TFT_HS,                //TFT 行同步信號
        TFT_VS,                //TFT 場同步信號
        TFT_BLANK,
        TFT_VCLK,
        TFT_DE
);
                       
        //---------------- 模塊輸入端口 ----------------
        input  Clk33M;          // 系統輸入時鍾 33MHZ
        input  Rst_n;
        input  [15:0]data_in;     // 待顯示數據
 
        //---------------- 模塊輸出端口 ----------------
        output [11:0]hcount;
        output [11:0]vcount;
        output [15:0]TFT_RGB;  //TFT 數據輸出
        output TFT_HS;           //TFT 行同步信號
        output TFT_VS;           //TFT 場同步信號
        output TFT_BLANK;
        output TFT_DE;
        output TFT_VCLK;
 
        //---------------- 內部寄存器定義 ----------------
        reg [11:0] hcount_r;     //TFT 行掃描計數器
        reg [11:0] vcount_r;     //TFT 場掃描計數器
        //---------------- 內部連線定義 ----------------
        wire hcount_ov;
        wire vcount_ov;
        wire TFT_DE;// 有效顯示區標定
 
        //TFT 行、場掃描時序參數表
        parameter TFT_HS_end=10'd1,
                                 hdat_begin=10'd46,
                                 hdat_end=10'd846,
                                 hpixel_end=12'd1056,
                                 TFT_VS_end=10'd1,
                                 vdat_begin=10'd24,
                                 vdat_end=10'd504,
                                 vline_end=10'd524;
        assign hcount=hcount_r;
        assign vcount=vcount_r;
       
        assign TFT_BLANK = Rst_n;
        assign TFT_VCLK = Clk33M;
 
        //**********************TFT 驅動部分 **********************
        // 行掃描
        always@(posedge Clk33M or negedge Rst_n)
        if(!Rst_n)
                hcount_r<=12'd0;
        else if(hcount_ov)
                hcount_r<=12'd0;
        else
                hcount_r<=hcount_r+12'd1;
 
        assign hcount_ov=(hcount_r==hpixel_end);
 
        // 場掃描
        always@(posedge Clk33M or negedge Rst_n)
        if(!Rst_n)
                vcount_r<=12'd0;
        else if(hcount_ov) begin
                if(vcount_ov)
                        vcount_r<=12'd0;
                else
                        vcount_r<=vcount_r+12'd1;
        end
        else
                vcount_r<=vcount_r;
               
        assign         vcount_ov=(vcount_r==vline_end);
 
        // 數據、同步信號輸出
        assign TFT_DE=((hcount_r>=hdat_begin)&&(hcount_r<hdat_end))
                                        &&((vcount_r>=vdat_begin)&&(vcount_r<vdat_end));
                                       
        assign TFT_HS=(hcount_r>TFT_HS_end);
        assign TFT_VS=(vcount_r>TFT_VS_end);
        assign TFT_RGB=(TFT_DE)?data_in:16'h000000;
               
endmodule
實驗結果:
<ignore_js_op>
Red
<ignore_js_op>
Green
<ignore_js_op>
Blue
<ignore_js_op>
Color_bar_h
<ignore_js_op>
Lattices image 1
 
  最后歡迎大家關注我的微信公眾號FPGA開源工作室。
<ignore_js_op>

轉載:http://www.openhw.org/module/forum/thread-658800-1-1.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM