【FPGA入门】第七篇、FPGA实现VGA接口驱动

目录

第一部分、实验结果

 1、横的三色彩条效果

2、竖的三色彩条效果

第二部分、VGA驱动基本知识

1、VGA分辨率问题        

2、VGA驱动波形

2.1、工业标准的时序波形图

2.2、比上面那张图更容易理解的图

2.3、每个区域对应的时间

2.4、不同分辨率的表格

3、VGA扫描范围问题

第三部分、VGA的时序波形图

第四部分、VGA的驱动代码

1、top-down结构图:

2、vga_ctrl.v模块代码:

3、top层代码

第五部分、总结


第一部分、实验结果

 1、横的三色彩条效果

  2、竖的三色彩条效果

【FPGA入门】第七篇、FPGA实现VGA接口驱动_第1张图片

第二部分、VGA驱动基本知识

        首先,关于VGA的深层次工作原理可以百度自行了解。

        我的理解比较简单,我记得高中的物理课的时候物理老师有提过老式电视机的显示原理,一般老式电视机的都特别大,而且都有个大屁股,这是因为后面有个电子枪,疯狂的朝着电视的屏幕喷射电子,然后就出现的显示,而且喷射的顺序就是从屏幕的左上角到右下角。而VGA的原理和这个类似。

1、VGA分辨率问题        

        首先不同分辨率对应的驱动程序是稍有区别的,正常情况下显示器都支持很多种分辨率,例如我电脑屏幕现在用的显示器分辨率为1920 * 1080@60Hz。(查看方式:选择 “开始 > 设置 > 系统 > 显示 > 高级显示器 )

【FPGA入门】第七篇、FPGA实现VGA接口驱动_第2张图片

         而本次实验选用的分辨率为640*480@60Hz60Hz为刷新频率,也就是1s钟电脑显示60张图片,也就是从电子束从屏幕的左上角到右下角这个过程执行了60次。

        这里发射的过程可以理解为扫描的过程,这样后面理解驱动程序时会简单许多。

2、VGA驱动波形

        2.1、工业标准的时序波形图

                HSync称作行同步信号VSync称作场同步信号或者垂直同步信号

【FPGA入门】第七篇、FPGA实现VGA接口驱动_第3张图片

         2.2、比上面那张图更容易理解的图

        图片来源于该篇博客http://t.csdn.cn/Hqvtc,有问题联系我删除​​​​​。这张图翻译了上面每条英文的意思。

【FPGA入门】第七篇、FPGA实现VGA接口驱动_第4张图片

【FPGA入门】第七篇、FPGA实现VGA接口驱动_第5张图片

         2.3、每个区域对应的时间

        这张图来源于哪一篇博客我忘记了(有问题联系我删除​​​​​),反正是一篇很好的博客,解释的更加透彻,每段时间点都标出来的。

【FPGA入门】第七篇、FPGA实现VGA接口驱动_第6张图片

        2.4、不同分辨率的表格

        该图片还是来源于该篇博客http://t.csdn.cn/Hqvtc,有问题联系我删除​​​​​。这个表格解释不同分辨率,同步,后沿等时间的区别。

        当然这里也有一个网址可以参考:VGA Signal Timing (tinyvga.com)

        这里不同分辨率的驱动时钟计算方法如下:

                                 时钟 = 行扫描周期 * 场扫描周期 * 刷新频率

以640*480@60分辨率的计算方式:

                                800 * 525 * 60 = 25,200,000 约等于 25MHz

【FPGA入门】第七篇、FPGA实现VGA接口驱动_第7张图片

3、VGA扫描范围问题

         看了上面的表格,不知道大家有没有有个问题,为什么分辨率640*480@60的行扫描为800(像素)而不是640(像素),场扫描为525(行数)而不是480(行数)?

        因为640只是有效图像的像素点长度,除了这些还有其他的也要考虑进去,所有像素点的总和才为800。如下图所示,真正显示在屏幕上的只是灰色区域。

【FPGA入门】第七篇、FPGA实现VGA接口驱动_第8张图片

第三部分、VGA的时序波形图

        由上面,关于VGA的时序了解了差不多,这里需要注意的是:行扫描时序要求(单位:像素,即输出一个像素的时间间隔),场扫描时序要求(单位:行,即输出一行的时间间隔)。

        将上面的波形图转换为更容易理解的波形图:

        这里分别引入行扫描计数器和场扫描计数器用来计时
 

【FPGA入门】第七篇、FPGA实现VGA接口驱动_第9张图片

第四部分、VGA的驱动代码

1、top-down结构图:

                gen_clk模块为由PLL锁相环产生的25MHz时钟,vga_ctrl为vga的驱动模块。

【FPGA入门】第七篇、FPGA实现VGA接口驱动_第10张图片

2、vga_ctrl.v模块代码:

// -----------------------------------------------------------------------------
// Copyright (c) 2014-2023 All rights reserved
// -----------------------------------------------------------------------------
// Author : BigFartPeach
// CSDN   : 大屁桃
// E-mail : [email protected]
// File   : vga_ctrl.v
// Create : 2023-06-06 14:23:19
// -----------------------------------------------------------------------------
module vga_ctrl(
	input wire clk_25M,
	input wire rst_n,
	output reg hsync,
	output reg vsync,
	output reg [7:0]rgb
	);
reg [9:0] hsync_cnt;
reg [9:0] vsync_cnt;

//行扫描计数器
always @(posedge clk_25M or negedge rst_n) begin
	if (rst_n == 0) begin
		hsync_cnt <= 'd0;
	end
	else if (hsync_cnt == 'd799) begin
		hsync_cnt <= 'd0;
	end
	else begin
		hsync_cnt <= hsync_cnt + 1'b1;
	end
end

//行同步信号
always @(posedge clk_25M or negedge rst_n) begin
	if (rst_n == 0) begin
		hsync <= 1'b1;
	end
	else if (hsync_cnt == 'd95) begin
		hsync <= 1'b0;
	end
	else if(hsync_cnt == 'd799)begin
		hsync <= 1'b1;
	end
end


//场扫描计数器
always @(posedge clk_25M or negedge rst_n) begin
	if (rst_n == 0) begin
		vsync_cnt <= 'd0;
	end
	else if (vsync_cnt == 'd524 && hsync_cnt == 'd799) begin
		vsync_cnt <= 'd0;
	end
	else if (hsync_cnt == 'd799) begin
		vsync_cnt <= vsync_cnt + 1'b1;
	end
end

//场扫描信号
always @(posedge clk_25M or negedge rst_n) begin
	if (rst_n == 0) begin
		vsync <= 1'b1;	
	end
	else if (hsync_cnt == 'd799 && vsync_cnt == 'd1) begin
		vsync <= 1'b0;
	end
	else if(hsync_cnt == 'd799 && vsync_cnt == 'd524) begin
		vsync <= 1'b1;
	end
end

//RGB信号输出 
always @(posedge clk_25M or negedge rst_n) begin
	if (rst_n == 0) begin
		rgb <= 'b000_000_00;	
	end
	//横彩条
	// else if (hsync_cnt>= 144 && hsync_cnt <= 783 && vsync_cnt>= 35 && vsync_cnt <= 194) begin
	// 	rgb <= 'b111_000_00;//红色
	// end
	// else if (hsync_cnt>= 144 && hsync_cnt <= 783 && vsync_cnt>= 195 && vsync_cnt <= 354)begin
	// 	rgb <= 'b000_111_00;//绿色
	// end
	// else if (hsync_cnt>= 144 && hsync_cnt <= 783 && vsync_cnt>= 355 && vsync_cnt <= 514)begin
	// 	rgb <= 'b000_000_11;//蓝色
	// end
	//竖彩条
	else if (hsync_cnt>= 144 && hsync_cnt <= 356 && vsync_cnt>= 35 && vsync_cnt <= 514) begin
		rgb <= 'b111_000_00;//红色
	end
	else if (hsync_cnt>= 357 && hsync_cnt <= 569 && vsync_cnt>= 35 && vsync_cnt <= 514) begin
		rgb <= 'b000_111_00;//绿色
	end
	else if (hsync_cnt>= 570 && hsync_cnt <= 783 && vsync_cnt>= 35 && vsync_cnt <= 514) begin
		rgb <= 'b000_000_11;//蓝色
	end
	else begin//其它区域
		rgb <= 'b000_000_00;//不显示
	end
end

endmodule

3、top层代码

// -----------------------------------------------------------------------------
// Copyright (c) 2014-2023 All rights reserved
// -----------------------------------------------------------------------------
// Author : BigFartPeach
// CSDN   : 大屁桃
// E-mail : [email protected]
// File   : top_vga.v
// Create : 2023-06-06 15:35:13
// -----------------------------------------------------------------------------
module top_vga(
	input wire clk,
	input wire rst_n,
	output wire hsync,
	output wire vsync,
	output wire [7:0] rgb
	);

wire clk_25M;

//PLL产生25M的时钟
gen_clk25 inst_clk25(
	// Clock in ports
	.CLK_IN1(clk),      // IN
	// Clock out ports
	.CLK_OUT1(clk_25M));    // OUT

//例化640*480@60Hz驱动模块
vga_ctrl inst_vga_ctrl (
	.clk_25M(clk_25M),
	.rst_n(rst_n),
	.hsync(hsync),
	.vsync(vsync),
	.rgb(rgb));


endmodule

第五部分、总结

        这里只是实现简单的驱动,后面的这篇文中我将VGA的驱动程序重新修改了一下,使整个程序更容易移植,有需要的哥们可以接着往后看。

        关于这篇文章的工程的代码如下,工程基于ISE软件,没积分的哥们评论留下邮箱即可

        FPGA入门第七篇、FPGA实现VGA接口驱动资源-CSDN文库

        最后,希望我的博客对你有帮助,有需要的小伙伴可以查看本专栏更多的往期文章专栏链接如下:FPGA的学习之旅_大屁桃的博客-CSDN博客

你可能感兴趣的:(FPGA的学习之旅,fpga开发)