基于Xlinx黑金ax309的VGA驱动模块设计

参考文章网址:

【开源骚客】:基于FPGA的摄像头视频显示系统——bilibili;

FPGA零基础学习:VGA协议驱动设计 - 知乎 (zhihu.com)

该文提及VGA的应用领域、母头公头的输入信号、借此解释VGA的原理,可先查看该文理解。

VGA(Video Graphics Array)视频图形阵列是 IBM 于1987年提出的一个使用模拟信号的电脑显示标准。VGA具有分辨率高、显示速率快、颜色丰富等优点。VGA 接口不但是CRT 显示设备的标准接口,同样也是 LCD 液晶显示设备的标准接口,具有广泛的应用范围。

用途:不仅用于接入CRT显示设备,同时可使用于 LCD 液晶显示设备的接入;

图片在数字设备中都是使用三基色组成:R(red)|G(green)|B(blue);

工作原理:

VGA的扫描方式是逐行扫描,也可以隔行扫描,但建议逐行扫描,即从显示器上像素点从第一扫到最后一个,再继续向下,到达右下角的最后一个点:

设备上查看原理图:以黑金Xlinx的AX309开发板举例,其原理图的VGA部分即:(其他开发可查询相关的VGA部分原理图)

VGA部分为右边,左边为R,G,B三部分的具体比例模块,正是使用这些比例来调配出65536种自然界人眼可辨认的颜色:

RED部分有五根引脚,GREEN有六根引脚,BLUE部分有五根引脚;

然后查看:VGA的通用驱动时序标准,咱们写时序逻辑设计时必须参照这个标准来写:

VESA标准及显示器时序标准.pdf (book118.com)

这里使用视频教学老师的800X600像素,里面有很多情况,可先尝试使用800X600像素再选择其他形式;

这是信号不同状态时所占的大概像素数,从上文我们已经可以得出每一行都是由像素扫描来完成的,像素即一个单位。

上面也已经说了,我们是由逐行扫描形式进行,那么每一行都要经历以下的各阶段变化,而每阶段大概占用多少的像素数在上面有所显示。  

  有提到,Hsync是行的同步信号,高电平时为一行的开始;(128像素点)

Vsync是场同步信号,为一幅图的新开始;

Addr_time为真实的有效区域;(占用800像素点)

由此可得设计思路:我们可以设计一个行计数器,一个场计数器:且上述说明中每个像素点扫描的时间都是40Mhz,两个计数器的时钟都是40Mhz

定义两个计数器,使用40Mhz让它进行工作;举例我们的正式行显示(addr_time)的前面有128+88pixels才开始显示内容,即在217pixels时开始显示。

以行举例:

[0-215]赋值全0;

[216-1016]显示我们需要的颜色;

列操作相同。

来到ISE Design14.7,创建一个新工程:以下为具体的模块及封装,在说明书pdf的模块下都是有显示的。

该界面展示的是项目的路径信息;

驱动模块代码:

module vga_drive(
//system signals
input     clk,
input     rst_n,
//vga_drive
output wire  H_sync,//行阵列
output wire  V_sync,//位阵列
output wire [15:0] rgb  //565的十六根RGB引脚(详见pdf)




);
  /*define parameter and internal signals*/
  
  localparam H_TOTAL_TIME 		= 		1056	;//整个时序链
  localparam H_ADDR_TIME		=		800	;//正式可用的部分
  localparam H_SYNC_TIME		=		128	;//正式
  localparam H_BACK_PORCH		=		88		;//结束的边界
  
  localparam V_TOTAL_TIME 		=		628	;//场的
  localparam V_ADDR_TIME  		=		600	;
  localparam V_SYNC_TIME 		=		4		;
  localparam V_BACK_PORCH		=		23		;//都对应pdf上的参数哦

  
  
  //定义两个计数器:行计数器和场计数器
   reg  [11:0] cnt_h;//位宽查看时序参数,行总时间为1056pixels,使用计数器换算为11bits
	reg  [9:0] cnt_v;//换算为10bits;
	
	//后面的参数也写进去
	 
  
  
  
  
  
  
  
  
  
  /*main code*/
  always@(posedge clk or negedge rst_n)begin//行时序逻辑
     if(!rst_n)
	    cnt_h   	<=			'd0;
	  end
	  else if(cnt_h>=H_TOTAL_TIME)
		 cnt_h		<=			'd0;
	  end
	  else 
	    cnt_h		<=			cnt_h+1'b1;
	  end
	  
	  
	  
	  
	  
	  
	  
	  
	  always@(posedge clk or negedge rst_n)begin//场的时序逻辑,根据行来计数
																//与行的不一样,因为场
																//的新触发条件是所有的行完成且场条件触发
																//所以为(cnt_v>=V_TOTAL_TIME&&cnt_h>=H_TOTAL_TIME)
																//这样的逻辑才对
     if(!rst_n)
	    cnt_v   	<=			'd0;
	  end
	  else if(cnt_v>=V_TOTAL_TIME&&cnt_h>=H_TOTAL_TIME)
		 cnt_v		<=			'd0;
	  end
	  else 	if(cnt_h>=H_TOTAL_TIME)					//行满之后才进行场计数
	    cnt_v		<=			cnt_v+1'b1;
	  end
	

//显示颜色部分
always@(posedge clk or negedge rst_n)begin
  if(!rst_n)begin
      vga			<=			'd0;
		
//场有效语句、行有效语句,参考例文的正方模块
	else if(cnt_v	>=(V_SYNC_TIME + V_BACK_PORCH)&&(cnt_v	<=  V_BACK_PORCH_+V_SYNC_TIME+V_ADDR_TIME))   
        if(cnt_h >=(H_SYNC_TIME+H_BACK_PORCH)&&(cnt_h<=H_BACK_PORCH+200+H_SYNC_TIME))
               vga <=  16'h0fff;
					else if(cnt_h >=(H_SYNC_TIME+H_BACK_PORCH+200))&&(cnt_h<=H_BACK_PORCH+400+H_SYNC_TIME))//注意>=和<号的逻辑区间				
					vga <=  16'hf0ff;
	else if(cnt_h >=(H_SYNC_TIME+H_BACK_PORCH+400))&&(cnt_h<=H_BACK_PORCH+600+H_SYNC_TIME))
					vga <=  16'hff0f;
	else if(cnt_h >=(H_SYNC_TIME+H_BACK_PORCH+600))&&(cnt_h<=H_BACK_PORCH+800+H_SYNC_TIME))
					vga <=  16'hff0f;
	else  
					vga <= 16'h0000;
	end
	
	else        vga <= 16'h0000;


	
		 
  
  /*赋值部分*/
   
  assign h_sync  		=			(cnt_h   <   H_SYNC_TIME)?1'b1:1'b0;
  assign v_sync		=			(cnt_v	<	 V_SYNC_TIME)?1'b1:1'b0;
  
  
  





endmodule

顶层模块代码中,需要添加驱动模块的例化语句;

这样一个能显示颜色的vga驱动模块的代码编写就完成了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值