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

  • 2019 年 10 月 29 日
  • 筆記

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

1,影像處理基礎知識

數字影像處理是指將影像訊號轉換成數字訊號並利用電腦對其進行處理的過程。影像處理最早出現於 20 世紀 50 年代,當時的電子電腦已經發展到一定水平,人們開始利用電腦來處理圖形和影像資訊。數字影像處理作為一門學科大約形成於 20 世紀 60 年代初期。早期的影像處理的目的是改善影像的品質,它以人為對象,以改善人的視覺效果為目的。影像處理中,輸入的是品質低的影像,輸出的是改善品質後的影像,常用的影像處理方法有影像增強、復原、編碼、壓縮等。

數字影像處理常用方法:

1 )影像變換:由於影像陣列很大,直接在空間域中進行處理,涉及計算量很大。因此,往往採用各種影像變換的方法,如傅立葉變換、沃爾什變換、離散餘弦變換等間接處理技術,將空間域的處理轉換為變換域處理,不僅可減少計算量,而且可獲得更有效的處理(如傅立葉變換可在頻域中進行數字濾波處理)。目前新興研究的小波變換在時域和頻域中都具有良好的局部化特性,它在影像處理中也有著廣泛而有效的應用。

2 )影像編碼壓縮:影像編碼壓縮技術可減少描述影像的數據量(即比特數),以便節省影像傳輸、處理時間和減少所佔用的存儲器容量。壓縮可以在不失真的前提下獲得,也可以在允許的失真條件下進行。編碼是壓縮技術中最重要的方法,它在影像處理技術中是發展最早且比較成熟的技術。

3 )影像增強和復原:影像增強和復原的目的是為了提高影像的品質,如去除雜訊,提高影像的清晰度等。影像增強不考慮影像降質的原因,突出影像中所感興趣的部分。如強化影像高頻分量,可使影像中物體輪廓清晰,細節明顯;如強化低頻分量可減少影像中雜訊影響。影像復原要求對影像降質的原因有一定的了解,一般講應根據降質過程建立「降質模型」,再採用某種濾波方法,恢復或重建原來的影像。

4 )影像分割:影像分割是數字影像處理中的關鍵技術之一。影像分割是將影像中有意義的特徵部分提取出來,其有意義的特徵有影像中的邊緣、區域等,這是進一步進行影像識別、分析和理解的基礎。雖然目前已研究出不少邊緣提取、區域分割的方法,但還沒有一種普遍適用於各種影像的有效方法。因此,對影像分割的研究還在不斷深入之中,是目前影像處理中研究的熱點之一。

5 )影像描述:影像描述是影像識別和理解的必要前提。作為最簡單的二值影像可採用其幾何特性描述物體的特性,一般影像的描述方法採用二維形狀描述,它有邊界描述和區域描述兩類方法。對於特殊的紋理影像可採用二維紋理特徵描述。隨著影像處理研究的深入發展,已經開始進行三維物體描述的研究,提出了體積描述、表面描述、廣義圓柱體描述等方法。

6 )影像分類(識別):影像分類(識別)屬於模式識別的範疇,其主要內容是影像經過某些預處理(增強、復原、壓縮)後,進行影像分割和特徵提取,從而進行判決分類。影像分類常採用經典的模式識別方法,有統計模式分類和句法(結構)模式分類,近年來新發展起來的模糊模式識別和人工神經網路模式分類在影像識別中也越來越受到重視。

隨著電腦技術的發展,影像處理技術已經深入到我們生活中的方方面面,其中,在娛樂休閑上的應用已經深入人心。影像處理技術在娛樂中的應用主要包括:電影特效製作、電腦電子遊戲、數位相機、影片播放、數字電視等。

電影特效製作:自從 20 世紀 60 年代以來,隨著電影中逐漸運用了電腦技術,一個全新的電影世界展現在人們面前,這也是一次電影的革命。越來越多的電腦製作的影像被運用到了電影作品的製作中。其視覺效果的魅力有時已經大大超過了電影故事的本身。如今,我們已經很難發現在一部電影中沒有任何的電腦數碼元素。

電腦電子遊戲:電腦電子遊戲的畫面,是近年來電子遊戲發展最快的部分之一。從 1996 年到現在,遊戲畫面的進步簡直可以用突飛猛進來形容,隨著影像處理技術的發展,眾多在幾年前無法想像的畫面在今天已經成為了平平常常的東西。

數位相機:所謂數位相機,是一種能夠進行拍攝,並通過內部處理把拍攝到的景物轉換成以數字格式存放影像的特殊照相機。與普通相機不同,數位相機並不使用膠片,而是使用固定的或者是可拆卸的半導體存儲器來保存獲取的影像。數位相機可以直接連接到電腦、電視機或者印表機上。在一定條件下,數位相機還可以直接接到移動式電話機或者手持 PC 機上。由於影像是內部處理的,所以使用者可以馬上檢查影像是否正確,而且可以立刻列印出來或是通過電子郵件傳送出去。

影片播放與數字電視:家庭影院中的 VCD , DVD 播放器和數字電視中,大量使用了影片編碼解碼等影像處理技術,而影片編碼解碼等影像處理技術的發展,也推動了影片播放與數字電視象高清晰,高畫質發展。

2,LCD顯示的基本原理

圖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的數字影像處理打下基礎。

模組劃分:

圖2 TFT5寸顯示器顯示FPGA模組結構

圖3 綜合後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: [email protected]

微信公眾號: 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

實驗結果:

Red

Green

Blue

color_bar_h

Lattices image 1