屏幕保護(hù)系統(tǒng)設(shè)計
實(shí)驗(yàn)任務(wù)
實(shí)驗(yàn)?zāi)康?/h3>在圖片顯示系統(tǒng)實(shí)驗(yàn)中我們學(xué)習(xí)過圖片取模的方法,根據(jù)取模數(shù)據(jù)創(chuàng)建ram模塊,本實(shí)驗(yàn)我們要學(xué)習(xí)VGA接口液晶顯示器的驅(qū)動原理及方法,結(jié)合圖片ram數(shù)據(jù),最終實(shí)現(xiàn)屏幕保護(hù)系統(tǒng)的總體設(shè)計。VGA接口顯示有固定的模式,本實(shí)驗(yàn)800×600@60Hz模式需要40MHz的時鐘主頻,可以按照簡易電壓表實(shí)驗(yàn)中的方法例化PLL的IP核實(shí)現(xiàn)。
本文引用地址:http://2s4d.com/article/202312/453983.htm設(shè)計框圖
根據(jù)前面的實(shí)驗(yàn)解析我們可以得知,該設(shè)計總體可以拆分成如下功能模塊實(shí)現(xiàn),
實(shí)驗(yàn)原理
VGA接口介紹
VGA(Video Graphics Array)是IBM在1987年隨PS/2機(jī)一起推出的一種視頻傳輸標(biāo)準(zhǔn),具有分辨率高、顯示速率快、顏色豐富等優(yōu)點(diǎn),在彩色顯示器領(lǐng)域得到了廣泛的應(yīng)用,VGA接口定義如下:
VGA接口定義如下:
一個標(biāo)準(zhǔn)的VGA接口硬件連接應(yīng)該有以下端口:
其中三色信號(RGB)都是模擬信號,行場同步信號(HSVS)都是數(shù)字信號。
對于VGA的接口模擬電壓(RGB),為0~0.714V范圍峰峰值,0代表無色,0.714代表滿色,一些非標(biāo)準(zhǔn)的顯示器使用的是1Vpp的滿色電平。三基色信號源端和終端匹配電阻均為75歐姆,如下圖所示:
FPGA為數(shù)字邏輯器件,想要得到0~0.714V范圍電壓主要有兩種方法,DAC轉(zhuǎn)換方式和電阻分壓方式,我們的擴(kuò)展板卡上就是采用的電阻分壓的方式,因VGA顯示器端有75歐的下拉電阻,為了得到0.714V的電壓我們給RGB信號線上串入270歐姆的電阻,3.3V*75/(270+75)=0.717V。如下圖所示:
當(dāng)FPGA驅(qū)動輸出高電平(3.3V)時,模擬分壓為0.714V,為滿色,當(dāng)FPGA驅(qū)動輸出低電平(0V)時,模擬分壓為0V,為無色,這樣RGB三基色都對應(yīng)兩種狀態(tài)輸出,共有2^3=8種顏色輸出。
VGA 接口時序是對其實(shí)現(xiàn)驅(qū)動與控制的關(guān)鍵所在,也是難點(diǎn)所在。難不光難在時序的產(chǎn)生,更多的是在于處理速度上的問題。VGA掃描顯示其實(shí)就是兩條線,一個是行掃描,一個是場掃描,在行有效和場有效的時候把數(shù)據(jù)發(fā)送給VGA即可顯示了。顯示標(biāo)準(zhǔn)就是行分辨率x列分辨率@60hz即一秒屏幕刷新60次,以800×600@60Hz模式為例,即行為800個像素,場為600個像素。
顯示器掃描一般采用逐行掃描的方式實(shí)現(xiàn):逐行掃描是掃描從屏幕左上角一點(diǎn)開始,從左像右逐點(diǎn)掃描,每掃描完一行,電子束回到屏幕的左邊下一行的起始位置,在這期間,CRT對電子束進(jìn)行消隱,行與行之間的返回過程稱為水平消隱,也稱行消隱(HBlank),每行結(jié)束時,用行同步信號進(jìn)行同步;當(dāng)掃描完所有的行,形成一幀,掃描點(diǎn)掃描完一幀后,要從圖像的右下角返回到圖像的左上角,開始新一幀的掃描,這一時間間隔,叫做垂直消隱,也稱場消隱(VBlank),用場同步信號進(jìn)行場同步。
VGA顯示常用模式列舉如下:
VGA模塊硬件連接
以下是STEP BaseBoard V3.0底板上的VGA模塊電路,其電路圖如下:
底板上的VGA顯示電路與1.8寸串行彩色液晶屏電路復(fù)用部分FPGA管腳,兩者不能同時使用,當(dāng)使用VGA接口模塊電路時,F(xiàn)PGA直接驅(qū)動VGA接口完成VGA液晶顯示器控制即可。VGA硬件采用電阻分壓方式連接,每個基色智能顯示無色或滿色,所以顯示效果最多有2^3=8種顏色顯示(包含黑色)。
VGA模塊驅(qū)動設(shè)計
端口列表中三基色控制管腳定義為vga[2:0],高位到低位依次接紅綠藍(lán),那么8中顏色對應(yīng)的數(shù)據(jù)如下:
output reg [2:0] vga; // vga,MSB~LSB = {R,G,B}
localparam RED = 3'b100, GREEN = 3'b010, BLUE = 3'b001;
localparam YELLOW = 3'b110, CYAN = 3'b011, PURPLE = 3'b101;
localparam WHITE = 3'b111, BLACK = 3'b000;
本實(shí)驗(yàn)使用800×600@60Hz的VGA顯示模式,首先將該VGA顯示模式下的參數(shù)定義,在40MHz的主頻下,參數(shù)如下:
水平方向
同步脈沖 Thp 后廊 Thb 有效線數(shù) Thd 前廊 Thf 128 88 800 40
垂直方向
同步脈沖 Thp 后廊 Thb 有效線數(shù) Thd 前廊 Thf 4 23 600 1
將參數(shù)定義,更改VGA顯示模式時,只需要更改下面參數(shù),參數(shù)定義如下:
//-- Horizonal timing information
`define HSYNC_A 16'd128 // 128
`define HSYNC_B 16'd216 // 128 + 88
`define HSYNC_C 16'd1016 // 128 + 88 + 800
`define HSYNC_D 16'd1056 // 128 + 88 + 800 + 40
//-- Vertical timing information
`define VSYNC_O 16'd4 // 4
`define VSYNC_P 16'd27 // 4 + 23
`define VSYNC_Q 16'd627 // 4 + 23 + 600
`define VSYNC_R 16'd628 // 4 + 23 + 600 + 1
根據(jù)VGA掃描的時序,在40MHz主頻時鐘下,每一行需要1056個主頻時鐘周期的時間,而每一幀需要628行掃描時間,我們定義兩個計數(shù)器,分別對主頻時鐘和行掃描進(jìn)行計數(shù),程序?qū)崿F(xiàn)如下:
reg [15:0] x_cnt,y_cnt;
always @ (posedge clk or negedge rst_n) // Count for HSYNC
if(!rst_n) x_cnt <= 16'd1;
else if(x_cnt == `HSYNC_D) x_cnt <= 16'd1;else x_cnt <= x_cnt + 1'b1;
always @ (posedge clk or negedge rst_n) // Count for VSYNC
if(!rst_n) y_cnt <= 16'd1;
else if(x_cnt == `HSYNC_D) begin
if(y_cnt == `VSYNC_R) y_cnt <= 16'd1;
else y_cnt <= y_cnt + 1'b1;
end else y_cnt <= y_cnt;
當(dāng)行計數(shù)器xcnt計數(shù)到1056且場計數(shù)器ycnt計數(shù)到628時,就是VGA掃描一幀的時間,行計數(shù)和場計數(shù)開始的時候?yàn)橥叫盘?,行場同步信號端口輸出,根?jù)時序要求程序?qū)崿F(xiàn)如下:
output reg sync_v; // sync_v
output reg sync_h; // sync_h
always @ (posedge clk or negedge rst_n) // HSYNC signal
if(!rst_n) sync_h <= 1'b1;
else if(x_cnt <= `HSYNC_A) sync_h <= 1'b0;
else sync_h <= 1'b1;
always @ (posedge clk or negedge rst_n) // VSYNC signal
if(!rst_n) sync_v <= 1'b1;
else if(y_cnt <= `VSYNC_O) sync_v <= 1'b0;
else sync_v <= 1'b1;
行同步和場同步的信號有了,接下來就是三基色數(shù)據(jù)的控制了,如果整個掃描過程中三基色端口一直輸出紅色數(shù)據(jù),那么我們就可以看到整個顯示器顯示紅色,整個掃描過程分為消隱區(qū)和顯示區(qū),只有在顯示區(qū)的數(shù)據(jù)才能顯示出來,落在消隱區(qū)的顏色數(shù)據(jù)沒有任何意義,顯示區(qū)就是當(dāng)行場計數(shù)器都在對應(yīng)有效線數(shù)的區(qū)間。即是說,如果我們讓三基色端口只在行計數(shù)器xcnt計數(shù)在216~1056之間且場計數(shù)器ycnt計數(shù)在27~627之間時輸出紅色數(shù)據(jù),依然可以看到整個顯示器顯示紅色。
屏幕保護(hù)實(shí)驗(yàn)需要小腳丫Logo圖片顯示并反彈移動,圖片顯示在液晶顯示器上我們需要知道圖片所在顯示區(qū)的坐標(biāo),圖片寬度和高度已知,我們以圖片左上角的像素點(diǎn)作為基點(diǎn),就可以知道圖片ram數(shù)據(jù)中每個數(shù)據(jù)對應(yīng)的坐標(biāo),假設(shè)我們知道了圖片基點(diǎn)的坐標(biāo)為(xset,yset)。圖片的顯示程序?qū)崿F(xiàn)如下:
注:這里講的坐標(biāo)是是以行計數(shù)器xcnt和場計數(shù)器ycnt為基準(zhǔn)的。
`define P_WIDTH 8'd128 // 圖片像素的水平寬度
`define P_DEPTH 8'd128 // 圖片像素的垂直高度
always @ (posedge clk or negedge rst_n) // rom address
if(!rst_n) rom_addr <= 1'b0;
else if((x_cnt>=x_set)&(x_cnt<(x_set+`P_WIDTH))&(y_cnt>=y_set)&(y_cnt<(y_set+`P_DEPTH)))
rom_addr <= y_cnt - y_set;else rom_addr <= rom_addr;
always @ (posedge clk or negedge rst_n) // rom data display
if(!rst_n) vga <= BLACK;
else if((x_cnt>=x_set)&(x_cnt<(x_set+`P_WIDTH))&(y_cnt>=y_set)&(y_cnt<(y_set+`P_DEPTH)))
if(rom_data[x_cnt - x_set]) vga <= color;
else vga <= BLACK;
else vga <= BLACK;
圖片可能顯示在屏幕的任何位置,那么基點(diǎn)(xset,yset)的移動軌跡范圍為上圖中紅色虛線框區(qū)域,只要控制基點(diǎn)移動和反彈就可以實(shí)現(xiàn)圖片的移動和反彈,這里需要考慮兩個參數(shù):移動速度和反彈方向。
移動速度
移動速度就是基點(diǎn)(xset,yset)變化的速度,我們設(shè)置一個計數(shù)器延遲來控制基點(diǎn)的變化速度,cnt的計數(shù)周期為2^19 * 1000ms / 12000000 = 44ms,基點(diǎn)坐標(biāo)每秒移動次數(shù)為1s / 44ms = 23次,計數(shù)程序?qū)崿F(xiàn)如下:
reg [18:0] cnt;
always @ (posedge clk or negedge rst_n) // delay count
if(!rst_n) cnt <= 1'b0;
else cnt <= cnt + 1'b1;
反彈方向
屏幕保護(hù)圖片碰到顯示器邊沿會反彈,反彈效果同鏡面反射一樣,與邊沿平行方向不變,垂直方向反向,所以行方向和場方向的反彈控制是相互獨(dú)立的,實(shí)現(xiàn)方法相同,這里我們以行(水平)方向的控制為例,程序?qū)崿F(xiàn)如下:
always @ (posedge clk or negedge rst_n) //水平方向反彈標(biāo)志
if(!rst_n) x_flag <= 1'b1;
else if(x_set == `HSYNC_B) x_flag <= 1'b1;
else if(x_set == (`HSYNC_C - `P_WIDTH)) x_flag <= 1'b0;
else x_flag <= x_flag;
always @ (posedge clk or negedge rst_n) //根據(jù)水平方向反彈標(biāo)志移動基點(diǎn)
if(!rst_n) x_set <= `HSYNC_B;
else if(!cnt) //控制基點(diǎn)行坐標(biāo)x_set的變化速度
if(x_flag) x_set <= x_set + 1'b1; //根據(jù)水平方向反彈標(biāo)志移動基點(diǎn)
else x_set <= x_set - 1'b1;
else x_set <= x_set;
系統(tǒng)總體實(shí)現(xiàn)
例化pll IP核得到40MHz時鐘信號,提供給VGA驅(qū)動模塊做時鐘信號,例化配置方法在簡易電壓表實(shí)驗(yàn)中有講解,這里不再重復(fù)。
屏幕保護(hù)圖片數(shù)據(jù)的ram模塊,提供小腳丫Logo圖片數(shù)據(jù),圖片顯示系統(tǒng)實(shí)驗(yàn)中也有相關(guān)內(nèi)容,調(diào)整一下圖像分辨率的寬度和高度就可以直接使用。
綜合后的設(shè)計框圖如下:
實(shí)驗(yàn)步驟
實(shí)驗(yàn)現(xiàn)象
將程序加載到FPGA中,使用VGA線連接液晶顯示器和FPGA底板,觀察顯示現(xiàn)象。小腳丫Logo圖片在顯示屏上移動,到達(dá)邊沿后反彈,每次反彈都會顏色改變,共有6中顏色。
在圖片顯示系統(tǒng)實(shí)驗(yàn)中我們學(xué)習(xí)過圖片取模的方法,根據(jù)取模數(shù)據(jù)創(chuàng)建ram模塊,本實(shí)驗(yàn)我們要學(xué)習(xí)VGA接口液晶顯示器的驅(qū)動原理及方法,結(jié)合圖片ram數(shù)據(jù),最終實(shí)現(xiàn)屏幕保護(hù)系統(tǒng)的總體設(shè)計。VGA接口顯示有固定的模式,本實(shí)驗(yàn)800×600@60Hz模式需要40MHz的時鐘主頻,可以按照簡易電壓表實(shí)驗(yàn)中的方法例化PLL的IP核實(shí)現(xiàn)。
本文引用地址:http://2s4d.com/article/202312/453983.htm根據(jù)前面的實(shí)驗(yàn)解析我們可以得知,該設(shè)計總體可以拆分成如下功能模塊實(shí)現(xiàn),
VGA(Video Graphics Array)是IBM在1987年隨PS/2機(jī)一起推出的一種視頻傳輸標(biāo)準(zhǔn),具有分辨率高、顯示速率快、顏色豐富等優(yōu)點(diǎn),在彩色顯示器領(lǐng)域得到了廣泛的應(yīng)用,VGA接口定義如下:
VGA接口定義如下:
一個標(biāo)準(zhǔn)的VGA接口硬件連接應(yīng)該有以下端口:
其中三色信號(RGB)都是模擬信號,行場同步信號(HSVS)都是數(shù)字信號。
對于VGA的接口模擬電壓(RGB),為0~0.714V范圍峰峰值,0代表無色,0.714代表滿色,一些非標(biāo)準(zhǔn)的顯示器使用的是1Vpp的滿色電平。三基色信號源端和終端匹配電阻均為75歐姆,如下圖所示:
FPGA為數(shù)字邏輯器件,想要得到0~0.714V范圍電壓主要有兩種方法,DAC轉(zhuǎn)換方式和電阻分壓方式,我們的擴(kuò)展板卡上就是采用的電阻分壓的方式,因VGA顯示器端有75歐的下拉電阻,為了得到0.714V的電壓我們給RGB信號線上串入270歐姆的電阻,3.3V*75/(270+75)=0.717V。如下圖所示:
當(dāng)FPGA驅(qū)動輸出高電平(3.3V)時,模擬分壓為0.714V,為滿色,當(dāng)FPGA驅(qū)動輸出低電平(0V)時,模擬分壓為0V,為無色,這樣RGB三基色都對應(yīng)兩種狀態(tài)輸出,共有2^3=8種顏色輸出。
VGA 接口時序是對其實(shí)現(xiàn)驅(qū)動與控制的關(guān)鍵所在,也是難點(diǎn)所在。難不光難在時序的產(chǎn)生,更多的是在于處理速度上的問題。VGA掃描顯示其實(shí)就是兩條線,一個是行掃描,一個是場掃描,在行有效和場有效的時候把數(shù)據(jù)發(fā)送給VGA即可顯示了。顯示標(biāo)準(zhǔn)就是行分辨率x列分辨率@60hz即一秒屏幕刷新60次,以800×600@60Hz模式為例,即行為800個像素,場為600個像素。
顯示器掃描一般采用逐行掃描的方式實(shí)現(xiàn):逐行掃描是掃描從屏幕左上角一點(diǎn)開始,從左像右逐點(diǎn)掃描,每掃描完一行,電子束回到屏幕的左邊下一行的起始位置,在這期間,CRT對電子束進(jìn)行消隱,行與行之間的返回過程稱為水平消隱,也稱行消隱(HBlank),每行結(jié)束時,用行同步信號進(jìn)行同步;當(dāng)掃描完所有的行,形成一幀,掃描點(diǎn)掃描完一幀后,要從圖像的右下角返回到圖像的左上角,開始新一幀的掃描,這一時間間隔,叫做垂直消隱,也稱場消隱(VBlank),用場同步信號進(jìn)行場同步。
VGA顯示常用模式列舉如下:
以下是STEP BaseBoard V3.0底板上的VGA模塊電路,其電路圖如下:
底板上的VGA顯示電路與1.8寸串行彩色液晶屏電路復(fù)用部分FPGA管腳,兩者不能同時使用,當(dāng)使用VGA接口模塊電路時,F(xiàn)PGA直接驅(qū)動VGA接口完成VGA液晶顯示器控制即可。VGA硬件采用電阻分壓方式連接,每個基色智能顯示無色或滿色,所以顯示效果最多有2^3=8種顏色顯示(包含黑色)。
端口列表中三基色控制管腳定義為vga[2:0],高位到低位依次接紅綠藍(lán),那么8中顏色對應(yīng)的數(shù)據(jù)如下:
output reg [2:0] vga; // vga,MSB~LSB = {R,G,B} localparam RED = 3'b100, GREEN = 3'b010, BLUE = 3'b001; localparam YELLOW = 3'b110, CYAN = 3'b011, PURPLE = 3'b101; localparam WHITE = 3'b111, BLACK = 3'b000;
本實(shí)驗(yàn)使用800×600@60Hz的VGA顯示模式,首先將該VGA顯示模式下的參數(shù)定義,在40MHz的主頻下,參數(shù)如下:
水平方向 | |||
同步脈沖 Thp | 后廊 Thb | 有效線數(shù) Thd | 前廊 Thf |
128 | 88 | 800 | 40 |
垂直方向 | |||
同步脈沖 Thp | 后廊 Thb | 有效線數(shù) Thd | 前廊 Thf |
4 | 23 | 600 | 1 |
將參數(shù)定義,更改VGA顯示模式時,只需要更改下面參數(shù),參數(shù)定義如下:
//-- Horizonal timing information `define HSYNC_A 16'd128 // 128 `define HSYNC_B 16'd216 // 128 + 88 `define HSYNC_C 16'd1016 // 128 + 88 + 800 `define HSYNC_D 16'd1056 // 128 + 88 + 800 + 40 //-- Vertical timing information `define VSYNC_O 16'd4 // 4 `define VSYNC_P 16'd27 // 4 + 23 `define VSYNC_Q 16'd627 // 4 + 23 + 600 `define VSYNC_R 16'd628 // 4 + 23 + 600 + 1
根據(jù)VGA掃描的時序,在40MHz主頻時鐘下,每一行需要1056個主頻時鐘周期的時間,而每一幀需要628行掃描時間,我們定義兩個計數(shù)器,分別對主頻時鐘和行掃描進(jìn)行計數(shù),程序?qū)崿F(xiàn)如下:
reg [15:0] x_cnt,y_cnt; always @ (posedge clk or negedge rst_n) // Count for HSYNC if(!rst_n) x_cnt <= 16'd1; else if(x_cnt == `HSYNC_D) x_cnt <= 16'd1;else x_cnt <= x_cnt + 1'b1; always @ (posedge clk or negedge rst_n) // Count for VSYNC if(!rst_n) y_cnt <= 16'd1; else if(x_cnt == `HSYNC_D) begin if(y_cnt == `VSYNC_R) y_cnt <= 16'd1; else y_cnt <= y_cnt + 1'b1; end else y_cnt <= y_cnt;
當(dāng)行計數(shù)器xcnt計數(shù)到1056且場計數(shù)器ycnt計數(shù)到628時,就是VGA掃描一幀的時間,行計數(shù)和場計數(shù)開始的時候?yàn)橥叫盘?,行場同步信號端口輸出,根?jù)時序要求程序?qū)崿F(xiàn)如下:
output reg sync_v; // sync_v output reg sync_h; // sync_h always @ (posedge clk or negedge rst_n) // HSYNC signal if(!rst_n) sync_h <= 1'b1; else if(x_cnt <= `HSYNC_A) sync_h <= 1'b0; else sync_h <= 1'b1; always @ (posedge clk or negedge rst_n) // VSYNC signal if(!rst_n) sync_v <= 1'b1; else if(y_cnt <= `VSYNC_O) sync_v <= 1'b0; else sync_v <= 1'b1;
行同步和場同步的信號有了,接下來就是三基色數(shù)據(jù)的控制了,如果整個掃描過程中三基色端口一直輸出紅色數(shù)據(jù),那么我們就可以看到整個顯示器顯示紅色,整個掃描過程分為消隱區(qū)和顯示區(qū),只有在顯示區(qū)的數(shù)據(jù)才能顯示出來,落在消隱區(qū)的顏色數(shù)據(jù)沒有任何意義,顯示區(qū)就是當(dāng)行場計數(shù)器都在對應(yīng)有效線數(shù)的區(qū)間。即是說,如果我們讓三基色端口只在行計數(shù)器xcnt計數(shù)在216~1056之間且場計數(shù)器ycnt計數(shù)在27~627之間時輸出紅色數(shù)據(jù),依然可以看到整個顯示器顯示紅色。
屏幕保護(hù)實(shí)驗(yàn)需要小腳丫Logo圖片顯示并反彈移動,圖片顯示在液晶顯示器上我們需要知道圖片所在顯示區(qū)的坐標(biāo),圖片寬度和高度已知,我們以圖片左上角的像素點(diǎn)作為基點(diǎn),就可以知道圖片ram數(shù)據(jù)中每個數(shù)據(jù)對應(yīng)的坐標(biāo),假設(shè)我們知道了圖片基點(diǎn)的坐標(biāo)為(xset,yset)。圖片的顯示程序?qū)崿F(xiàn)如下:
注:這里講的坐標(biāo)是是以行計數(shù)器xcnt和場計數(shù)器ycnt為基準(zhǔn)的。
`define P_WIDTH 8'd128 // 圖片像素的水平寬度 `define P_DEPTH 8'd128 // 圖片像素的垂直高度 always @ (posedge clk or negedge rst_n) // rom address if(!rst_n) rom_addr <= 1'b0; else if((x_cnt>=x_set)&(x_cnt<(x_set+`P_WIDTH))&(y_cnt>=y_set)&(y_cnt<(y_set+`P_DEPTH))) rom_addr <= y_cnt - y_set;else rom_addr <= rom_addr; always @ (posedge clk or negedge rst_n) // rom data display if(!rst_n) vga <= BLACK; else if((x_cnt>=x_set)&(x_cnt<(x_set+`P_WIDTH))&(y_cnt>=y_set)&(y_cnt<(y_set+`P_DEPTH))) if(rom_data[x_cnt - x_set]) vga <= color; else vga <= BLACK; else vga <= BLACK;
圖片可能顯示在屏幕的任何位置,那么基點(diǎn)(xset,yset)的移動軌跡范圍為上圖中紅色虛線框區(qū)域,只要控制基點(diǎn)移動和反彈就可以實(shí)現(xiàn)圖片的移動和反彈,這里需要考慮兩個參數(shù):移動速度和反彈方向。
移動速度
移動速度就是基點(diǎn)(xset,yset)變化的速度,我們設(shè)置一個計數(shù)器延遲來控制基點(diǎn)的變化速度,cnt的計數(shù)周期為2^19 * 1000ms / 12000000 = 44ms,基點(diǎn)坐標(biāo)每秒移動次數(shù)為1s / 44ms = 23次,計數(shù)程序?qū)崿F(xiàn)如下:
reg [18:0] cnt; always @ (posedge clk or negedge rst_n) // delay count if(!rst_n) cnt <= 1'b0; else cnt <= cnt + 1'b1;
反彈方向
屏幕保護(hù)圖片碰到顯示器邊沿會反彈,反彈效果同鏡面反射一樣,與邊沿平行方向不變,垂直方向反向,所以行方向和場方向的反彈控制是相互獨(dú)立的,實(shí)現(xiàn)方法相同,這里我們以行(水平)方向的控制為例,程序?qū)崿F(xiàn)如下:
always @ (posedge clk or negedge rst_n) //水平方向反彈標(biāo)志 if(!rst_n) x_flag <= 1'b1; else if(x_set == `HSYNC_B) x_flag <= 1'b1; else if(x_set == (`HSYNC_C - `P_WIDTH)) x_flag <= 1'b0; else x_flag <= x_flag; always @ (posedge clk or negedge rst_n) //根據(jù)水平方向反彈標(biāo)志移動基點(diǎn) if(!rst_n) x_set <= `HSYNC_B; else if(!cnt) //控制基點(diǎn)行坐標(biāo)x_set的變化速度 if(x_flag) x_set <= x_set + 1'b1; //根據(jù)水平方向反彈標(biāo)志移動基點(diǎn) else x_set <= x_set - 1'b1; else x_set <= x_set;
例化pll IP核得到40MHz時鐘信號,提供給VGA驅(qū)動模塊做時鐘信號,例化配置方法在簡易電壓表實(shí)驗(yàn)中有講解,這里不再重復(fù)。
屏幕保護(hù)圖片數(shù)據(jù)的ram模塊,提供小腳丫Logo圖片數(shù)據(jù),圖片顯示系統(tǒng)實(shí)驗(yàn)中也有相關(guān)內(nèi)容,調(diào)整一下圖像分辨率的寬度和高度就可以直接使用。
綜合后的設(shè)計框圖如下:
將程序加載到FPGA中,使用VGA線連接液晶顯示器和FPGA底板,觀察顯示現(xiàn)象。小腳丫Logo圖片在顯示屏上移動,到達(dá)邊沿后反彈,每次反彈都會顏色改變,共有6中顏色。
評論