zoukankan      html  css  js  c++  java
  • VGA接口之显示彩色条

    本博文介绍下spartan-3e start kit board上的VGA接口的用法。

    一、VGA简介

    VGA(Video Graphics Array)是IBM于1987年提出的一个使用模拟信号的电脑显示标准,最早指的是显示器

    640X480这种显示模式。本实验程序用的是640X480模式,即每一行有640个像素,整个显示区域一共有480

    行。VGA接口是一种D型接口,采用非对称分布的15pin 连接方式,共有15针,分成3排,每排5个孔。本实验条

    件下只使用其中5个pin,分别是红色信号输入(R)、绿色信号输入(G)、蓝色信号输入(B),行同步信号输入(h_sync)

    和场同步信号输入(v_sync)。

    二、VGA时序

    VGA的扫描顺序是从左到右,从上到下。例如在640X480的显示模式下,从显示器的左上角开始往右扫描,直到

    640个像素扫完,再回到最左边,开始第二行的扫描,如此往复,到第480行扫完时即完成一帧图像的显示。这时

    又回到左上角,开始下一帧图像的扫描。如果每秒能完成60帧,则称屏幕刷新频率为60Hz。宏观上,一帧屏幕由

    480个行和640个列填充而成,而实际上,一帧屏幕除了显示区,还包含其他未显示部分,作为边框或者用来同步。

    具体而言,一个完整的行同步信号包含了左边框、显示区、右边框还有返回区四个部分,总共800个像素,其分配

    如下:

    左边框:48

    显示区:640

    右边框:16

    返回区:96

    同样的,一个完整的垂直同步信号也分为四个区域,总共525个像素,分配如下:

    顶边框:33

    显示区:480

    底边框:10

    返回区:2

    三、VGA在各种像素及刷新频率下的各段长度对照表

    四、VGA显示颜色编码表

    五、实验设计

    1、K17作为复位键,按下后各种信号均清零,屏幕显示黑色。

    2、滑动开关SW0(L13)、SW1(L14)作为输入,当SW1 SW0=00,屏幕竖向显示8种颜色;当SW1 SW0=01,屏幕

    横向显示8种颜色;当SW1 SW0=1X,屏幕只显示一种颜色。

    六、实验结果

    六、不得不说的一些问题

    1、用VGA连接线将板子上的接口与笔记本的接口连起来,一点反应都没有?!

    因为笔记本上的VGA接口是输出口,不能输入!也基本就是说要把VGA连接线接到台式机的显示屏才可以做出

    结果来。

    2、VGA频率的计算?

    就是相应像素x刷新频率了。就本实验来说就是800*525*60=25200000HZ了。所以在verilog源码中可以看到已

    经对板子的频率(50MHZ)二分频(25MHZ)了。

    3、从上面的VGA时序图中可以发现行、场同步信号都是低电平有效。行场同步期间以及显示前沿、显示后沿

    其中,输出RGB信号都是无效的,此时RGB=3'b000,否则无法正常显示。

    4、扫描是从上到下、从左到右依次进行的。每次电子束其实只是扫描到一个像素点罢了,由于扫描速度很快,

    我们感觉是全部扫描的。

    5、代码中必须确定每一个像素点的RGB信号值。这也就是说代码中必须有对行列的计数值。行为800个像素,

    行同步96+显示后沿48=144个像素是不用显示的。此后显示640个像素。再然后显示前沿16个像素也不显示。

    列的显示同理可推。

    七、代码

    1、verilog源码

    module VGA( CLK, RST, DIN, DOUT,VGA_HSYNC, VGA_VSYNC );
    input CLK; // System clock= 50MHz
    input RST; // high active
    input [1:0] DIN;
    output [2:0] DOUT;// RGB
    output VGA_HSYNC;
    output VGA_VSYNC;
    
    reg [2:0] RGB;
    reg [9:0] h_cnt;//horizontal counter
    reg [9:0] v_cnt; // vertical counter
    reg VGA_CLK; // VGA clock = 25MHz
    wire [1:0] state;
    wire data_valid;
    
    assign DOUT = data_valid ? RGB:3'd0;   //数据无效时,RGB必须为全0
    assign state = DIN;
    assign VGA_HSYNC = ( h_cnt >= 10'd96 )? 1'b1 : 1'b0;
    assign VGA_VSYNC = ( v_cnt >= 10'd2 )? 1'b1 : 1'b0;
    
    assign data_valid = ((h_cnt > 10'd143) && (h_cnt < 10'd784) && (v_cnt > 10'd34) && (v_cnt < 10'd515));
    
    /////// Generate VGA CLOCK = 25MHz ///////
    always @ (posedge CLK or posedge RST)begin
    	if(RST) VGA_CLK <= 1'b0;
    	else VGA_CLK <= ~VGA_CLK;
    end
    
    /////// horizontal counter ///////
    always @(posedge VGA_CLK or posedge RST)begin
    	if(RST) h_cnt <= 10'd0;
    	else if (h_cnt == 10'd799) h_cnt <= 10'd0;
    	else  h_cnt <= h_cnt + 1'b1;
    end
    
    /////// vertical counter ///////
    always @(posedge VGA_CLK or posedge RST)begin
    	if(RST) v_cnt <= 10'd0;
    	else if (v_cnt == 10'd524) v_cnt <= 10'd0;
    	else if(h_cnt == 10'd799) v_cnt <= v_cnt + 1'b1; 
    	else v_cnt <= v_cnt;	
    end
    
    always @ (posedge CLK or posedge RST) begin
    	if(RST) begin
    	   RGB <= 3'd0;
    	end
    	else begin
    	 case (state)
    	  2'b00: begin
    				 if      ((h_cnt > 10'd143) && (h_cnt <= 10'd223)) RGB <= 3'd000;
    				 else if ((h_cnt > 10'd223) && (h_cnt <= 10'd303)) RGB <= 3'b001;
    				 else if ((h_cnt > 10'd303) && (h_cnt <= 10'd383)) RGB <= 3'b010;
    				 else if ((h_cnt > 10'd383) && (h_cnt <= 10'd463)) RGB <= 3'b011;
    				 else if ((h_cnt > 10'd463) && (h_cnt <= 10'd543)) RGB <= 3'b100;
    				 else if ((h_cnt > 10'd543) && (h_cnt <= 10'd623)) RGB <= 3'b101;
    				 else if ((h_cnt > 10'd623) && (h_cnt <= 10'd703)) RGB <= 3'b110;
    				 else if ((h_cnt > 10'd703) && (h_cnt <= 10'd783)) RGB <= 3'b111;
    	          end
    	  2'b01: begin
    				  if      ((v_cnt > 10'd34)  && (v_cnt <= 10'd94))  RGB <= 3'd000;
    				  else if ((v_cnt > 10'd94)  && (v_cnt <= 10'd154)) RGB <= 3'b001;
    				  else if ((v_cnt > 10'd154) && (v_cnt <= 10'd214)) RGB <= 3'b010;
    				  else if ((v_cnt > 10'd214) && (v_cnt <= 10'd274)) RGB <= 3'b011;
    				  else if ((v_cnt > 10'd274) && (v_cnt <= 10'd334)) RGB <= 3'b100;
    				  else if ((v_cnt > 10'd334) && (v_cnt <= 10'd394)) RGB <= 3'b101;
    				  else if ((v_cnt > 10'd394) && (v_cnt <= 10'd454)) RGB <= 3'b110;
    				  else if ((v_cnt > 10'd454) && (v_cnt <= 10'd514)) RGB <= 3'b111;
    		       end
    		default: RGB <= 3'b101;
    		endcase
    	end
    end
    endmodule
    

    2、ucf约束文件

    NET "CLK"        LOC = "C9" | IOSTANDARD = LVCMOS33 ;
    NET "CLK"        PERIOD = 20.0ns HIGH 40%;
    NET "RST"        LOC = "K17" | IOSTANDARD = LVTTL  | PULLDOWN ; 
    NET "DOUT[2]"    LOC = "H14" | IOSTANDARD = LVTTL  | DRIVE = 8  | SLEW = FAST ;
    NET "DOUT[1]"    LOC = "H15" | IOSTANDARD = LVTTL  | DRIVE = 8  | SLEW = FAST ;
    NET "DOUT[0]"    LOC = "G15" | IOSTANDARD = LVTTL  | DRIVE = 8  | SLEW = FAST ;  
    NET "VGA_VSYNC"  LOC = "F14" | IOSTANDARD = LVTTL  | DRIVE = 8  | SLEW = FAST ;
    NET "VGA_HSYNC"  LOC = "F15" | IOSTANDARD = LVTTL  | DRIVE = 8  | SLEW = FAST ;
    NET "DIN[0]"     LOC = "L13" | IOSTANDARD = LVTTL | PULLUP ; 
    NET "DIN[1]"     LOC = "L14" | IOSTANDARD = LVTTL | PULLUP ; 
  • 相关阅读:
    什么是 canvas(画布)?
    JavaScript
    JavaScript函数
    JavaScript事件
    JavaScript获取元素
    文件拷贝——高淇JAVA300讲笔记之IO和File
    读取与写出文件——高淇JAVA300讲笔记之IO和File
    File类的常用方法2——高淇JAVA300讲笔记之IO和File
    File类的常用方法1——高淇JAVA300讲笔记之IO和File
    路径常量,绝对路径与相对路径,构造File对象——高淇JAVA300讲笔记之IO和File
  • 原文地址:https://www.cnblogs.com/xinyuyuanm/p/2979647.html
Copyright © 2011-2022 走看看