基于STEP FPGA的8色VGA功能驅(qū)動
硬件說明
VGA(video graphics array)即視頻圖形陣列,是IBM在1987年隨PS/2一起推出的使用模擬信號的一種視頻傳輸標(biāo)準(zhǔn)。VGA接口分公口和母口,如下圖:
VGA接口引腳定義如下:
一個標(biāo)準(zhǔn)的VGA接口應(yīng)該有以下端口:
三色信號都是模擬信號,行場同步信號都是數(shù)字信號;
對于VGA的接口模擬電壓,為0~0.714V,0代表無色,0.714代表滿色,F(xiàn)PGA輸出3.3V,所以還必須要經(jīng)過DAC的轉(zhuǎn)換?,F(xiàn)今有兩種比較成熟的方法:電阻分壓方式和DAC轉(zhuǎn)換方式。
我們的底板上就是采用的電阻分壓的方式,因VGA顯示器端有75歐的下拉電阻,為了得到0.714V的電壓我們給RGB信號線上串入270歐的電阻,3.3V*75/(270+75)=0.717V。如下
VGA驅(qū)動顯示器用的是掃描的方式,逐行掃描the HS (Horizontal Synchronization)逐行掃描是掃描從屏幕的左上角一點(diǎn)開始,由左向右逐點(diǎn)掃描,每掃描完一行,電子束回到屏幕的左邊下一行的起始位置,在這期間CRT(陰極射線顯像管)對電子束進(jìn)行消隱,每行結(jié)束時,用行同步信號進(jìn)行同步;當(dāng)掃描完所有行之后形成一幀,用場同步信號進(jìn)行同步,并使掃描回到屏幕左上方,同時進(jìn)行場消隱,開始下一幀。VGA一直在掃描,每一場的掃描包括了若干行掃描,依次循環(huán);
VGA顯示時序如下:
VGA顯示區(qū)域和消隱區(qū)域:
常見的VGA顯示模式:
Verilog代碼
// -------------------------------------------------------------------- // >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<< // -------------------------------------------------------------------- // Module: Param_define // // Author: Step // // Description: Param_define // // -------------------------------------------------------------------- // Code Revision History : // -------------------------------------------------------------------- // Version: |Mod. Date: |Changes Made: // V1.1 |2016/10/30 |Initial ver // -------------------------------------------------------------------- `timescale 1ns / 1ns //VGA顯示器驅(qū)動只需要5個信號即可(行同步、場同步、紅色、綠色、藍(lán)色信號) //紅綠藍(lán)三色信號為模擬信號,輸入電壓范圍為0.0V~0.7V //VGA時序中行同步和場同步都分為四個階段(同步脈沖、后廊、有效線數(shù)、前廊) //VGA顯示有很多模式,每種模式都是有固定的時鐘和時序參數(shù),需要根據(jù)要求控制 `ifdef VGA_800X600_60Hz //不同VGA顯示模式相應(yīng)的參數(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 //行同步脈沖+后廊+有效線數(shù)+前廊 //-- 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 //場同步脈沖+后廊+有效線數(shù)+前廊 //--------------------------------------------------------------------------- `endif `ifdef VGA_640X480_85Hz //不同VGA顯示模式相應(yīng)的參數(shù) //--------------------------------------------------------------------------- //-- Horizonal timing information`define HSYNC_A 16'd48 // 48`define HSYNC_B 16'd160 // 48 + 112`define HSYNC_C 16'd800 // 48 + 112 + 640`define HSYNC_D 16'd832 // 48 + 112 + 640 + 32 //行同步脈沖+后廊+有效線數(shù)+前廊 //-- Vertical timing information`define VSYNC_O 16'd3 // 3 `define VSYNC_P 16'd28 // 3 + 25`define VSYNC_Q 16'd508 // 3 + 25 + 480`define VSYNC_R 16'd509 // 3 + 25 + 480 + 1 //場同步脈沖+后廊+有效線數(shù)+前廊 //--------------------------------------------------------------------------- `endif
// -------------------------------------------------------------------- // >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<< // -------------------------------------------------------------------- // Module: Vga_Module // // Author: Step // // Description: Vga_Module // // -------------------------------------------------------------------- // Code Revision History : // -------------------------------------------------------------------- // Version: |Mod. Date: |Changes Made: // V1.1 |2016/10/30 |Initial ver // -------------------------------------------------------------------- `define VGA_800X600_60Hz //定義使用的VGA顯示模式 `ifdef VGA_800X600_60Hz //根據(jù)VGA顯示模式的定義調(diào)用相應(yīng)的參數(shù) `include "Param_define.v" //調(diào)用Param_define.v文件中的全局定義 `endif module Vga_Module ( input clk_in, //40MHz系統(tǒng)時鐘 input rst_n_in, //系統(tǒng)復(fù)位,低有效 output reg sync_v, //VGA場同步sync_v output reg sync_h, //VGA行同步sync_h output reg [2:0] vga_data //VGA數(shù)據(jù)MSB~LSB = {R,G,B} ); reg [15:0] x_cnt; reg [15:0] y_cnt; reg vga_valid; //對時鐘計(jì)數(shù)標(biāo)識VGA一次行掃描需要的時間 always @ (posedge clk_in or negedge rst_n_in) if(!rst_n_in) x_cnt <= 16'd0; //復(fù)位時初始值 else if(x_cnt >= `HSYNC_D) x_cnt <= 16'd0; //一次行掃描需要1056個時鐘(128+88+800+40) else x_cnt <= x_cnt + 1'b1; //對行掃描計(jì)數(shù)標(biāo)識VGA一次場掃描需要的時間 always @ (posedge clk_in or negedge rst_n_in) if(!rst_n_in) y_cnt <= 16'd0; //復(fù)位時初始值 else if(x_cnt == `HSYNC_D) begin //每次行掃描時 if(y_cnt >= `VSYNC_R) y_cnt <= 16'd0; //每次場掃描包含628次行掃描 else y_cnt <= y_cnt + 1'b1; end else y_cnt <= y_cnt; //在每次行掃描過程中場掃描計(jì)數(shù)器保持不變 //按照顯示模式的參數(shù)產(chǎn)生行同步掃描的脈沖 always @ (posedge clk_in or negedge rst_n_in) if(!rst_n_in) sync_h <= 1'b1; else if(x_cnt < `HSYNC_A) sync_h <= 1'b0; else sync_h <= 1'b1; //按照顯示模式的參數(shù)產(chǎn)生場同步掃描的脈沖 always @ (posedge clk_in or negedge rst_n_in) if(!rst_n_in) sync_v <= 1'b1; else if(y_cnt < `VSYNC_O) sync_v <= 1'b0; else sync_v <= 1'b1; //根據(jù)行場同步信號的有效線數(shù)確定有效顯示區(qū)域 always @ (posedge clk_in or negedge rst_n_in) if(!rst_n_in) vga_valid <= 1'b0; else if((x_cnt > `HSYNC_B) && (x_cnt <`HSYNC_C) && (y_cnt > `VSYNC_P) && (y_cnt < `VSYNC_Q)) vga_valid <= 1'b1; //有效顯示區(qū)域中vga_valid標(biāo)志為1 else vga_valid <= 1'b0; //在VGA有效顯示區(qū)域不同的段顯示不同的顏色 always @ (posedge clk_in or negedge rst_n_in)begin if(!rst_n_in) vga_data = 3'b111; else if(vga_valid)begin //在有效顯示區(qū)域內(nèi) if((x_cnt > `HSYNC_B) && (x_cnt <= `HSYNC_B + 10'd100)) vga_data = 3'b100; //紅色 else if((x_cnt > `HSYNC_B + 10'd100) && (x_cnt <= `HSYNC_B + 10'd200)) vga_data = 3'b010; //綠色 else if((x_cnt > `HSYNC_B + 10'd200) && (x_cnt <= `HSYNC_B + 10'd300)) vga_data = 3'b001; //藍(lán)色 else if((x_cnt > `HSYNC_B + 10'd300) && (x_cnt <= `HSYNC_B + 10'd400)) vga_data = 3'b110; //黃色 else if((x_cnt > `HSYNC_B + 10'd400) && (x_cnt <= `HSYNC_B + 10'd500)) vga_data = 3'b101; //紫色 else if((x_cnt > `HSYNC_B + 10'd500) && (x_cnt <= `HSYNC_B + 10'd600)) vga_data = 3'b011; //青色 else if((x_cnt > `HSYNC_B + 10'd600) && (x_cnt <= `HSYNC_B + 10'd700)) vga_data = 3'b111; //白色 else if((x_cnt > `HSYNC_B + 10'd700) && (x_cnt <= `HSYNC_B + 10'd800)) vga_data = 3'b000; //黑色 else vga_data = 3'b111; //白色 end else vga_data = 3'b111; //白色end endmodule
小結(jié)
本節(jié)主要為大家講解了VGA顯示的原理、時序及軟件設(shè)計(jì),需要大家掌握的同時自己創(chuàng)建工程,通過整個設(shè)計(jì)流程,生成FPGA配置文件加載測試。
評論