阅读 58

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 ;


文章分类
代码人生
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐