赞
踩
VGA(Video Graphics Array)是一种显示接口标准,它最初由IBM于1987年推出。VGA协议定义了计算机视频输出信号的格式和特性。它主要用于连接计算机和显示器之间的传输,实现图像和视频的显示。
VGA协议支持最高分辨率为640x480像素,色彩深度为16位色(即65,536种颜色)。它使用模拟信号传输,通过15个针脚的连接器将图像信号传送到显示器。VGA协议还定义了一些控制信号,用于在显示设备上调整图像的参数,例如水平和垂直同步信号、显示器ID等。
尽管VGA协议的分辨率和色彩深度相对较低,但它是计算机和显示器之间的广泛接口,被广泛应用于台式机、笔记本电脑和显示器等设备上。
VGA15针接口 标准VGA母接口
主要针介绍:
VGA 15针端口,也称为VGA D-sub 15针接口,是常见的VGA连接器,用于连接计算机和显示器之间的视频信号传输。下面是VGA 15针端口的功能介绍:
1. 红色信号(Red):通过这个引脚传输红色信号,用于显示图像中的红色分量。
2. 绿色信号(Green):通过这个引脚传输绿色信号,用于显示图像中的绿色分量。
3. 蓝色信号(Blue):通过这个引脚传输蓝色信号,用于显示图像中的蓝色分量。
4. 水平同步信号(HSync):通过这个引脚传输水平同步信号,用于同步显示器上图像的扫描行。
5. 垂直同步信号(VSync):通过这个引脚传输垂直同步信号,用于同步显示器上图像的扫描帧。
6. 地线(Ground):这些引脚用于电路的接地连接,确保信号的稳定和可靠传输。
7. DDC(Display Data Channel):这个引脚允许计算机和显示器之间进行双向通信,以交换显示器的信息和设置。
VGA 15针接口是模拟信号接口,支持最高分辨率为640x480像素。
由下图不难看出Red管脚有5个输入端,Green有6个输入端口,Blue有5个端口,且都只有一个输出端口,也就是说在输出时他们分别输送5位、6位、5位表示的颜色数据,而这些端口共有16位用来表示不同颜色,2的16次方是65536种不同的颜色数据
由于人的肉眼有感知 红 绿 蓝 三种不同颜色的锥体细胞,因此色彩空间通常可以由三种基本色来表达。三种基色是相互独立的,任何一种基色都不能有其它两种颜色合成。红 绿 蓝 是三基色,这三种颜色合成的颜色范围最为广泛。我们的RGB信号就是三基色的运用,对这三个信号赋予不同的数值,混合起来便是不同的色彩
VGA成像扫描原理是指VGA显示器是如何通过扫描线和逐行显示的方式来显示图像的。
下面是VGA成像扫描原理的简要介绍:
1. 水平扫描线:VGA显示器从左到右,一行一行地扫描整个屏幕。每一行开始时,水平同步信号(HSync)会告诉显示器开始新行的扫描。显示器通过红色、绿色和蓝色的信号输入,根据每个像素的颜色值来显示相应的颜色。
行时序:
2. 垂直扫描帧:当一行扫描完成后,垂直同步信号(VSync)会告诉显示器开始新的帧扫描。显示器从上到下,一帧一帧地扫描整个屏幕。垂直同步信号会告诉显示器开始扫描新帧的第一行。
列时序:
3. 刷新率:VGA显示器的刷新率指的是每秒钟显示的帧数。一般情况下,VGA显示器的刷新率为72Hz,意味着显示器可以每秒刷新72帧图像。每个帧由多个扫描行组成,每一行由多个像素点组成。
每帧的时序:
(声明:该图片转自图片右下角博主)找了好多图都没找到比这更好的
4. 分辨率:VGA显示器的分辨率指的是水平和垂直方向上的像素数。常见的VGA分辨率是800x600像素,意味着每行显示800个像素,每帧显示600行。
通过不断扫描每个像素点,并根据其颜色值来显示相应的颜色,VGA显示器可以逐行逐行地构建整个图像。由于VGA采用模拟信号传输,图像的质量可能受到干扰或信号衰减的影响,导致图像出现模糊、噪点或失真等问题。
以800*600/72Hz为例,800*600/72Hz是指刷新频率为72Hz,分辨率为800X600。这个是标准 VGA 显示驱动。
刷新频率为72Hz,是指1秒显示72幅图像。
从表中可以看出,该分辨率行同步信号,同步脉冲是120个基准时钟,显示后沿是84个基准时钟,显示区域是800个基准时钟,显示前沿是16个基准时钟,那么一行一共有1040个基准时钟。
该分辨率场同步信号,同步脉冲是6行(6*1040个基准时钟),显示后沿是23行(23*1040个基准时钟),显示区域为600行(600*1040个基准时钟),显示前沿为37行(37*1040个基准时钟),一共有666行(666*1040个基准时钟)。
基准时钟是多少呢?由于1秒显示72幅图像,所以一幅图像显示的时间是1/72秒。一幅图像占用了1040*666个基准时钟,所以基准时钟周期=(1/72)/(1040*666)秒,约为20.0521ns。那么基准时钟周期就约为50 MHz ,实验中我们取50M(正好是开发板EP4CE22F17C6的系统时钟,不需要再另外分频)。
1:实现八种颜色全屏显示,且要求每秒变换一种颜色,并将颜色的序号通过数码管显示
2:竖条纹显示
3:横条纹显示
4:棋盘间隔显示
模块名要与工程名相同,文件名可以不一样
- module VGA4( //顶层模块:将各个模块组合
- //外部接口
- input clk, //系统时钟50MHz
- input rst_n,//低电平复位
- input[1:0] button,
- output clkout_1s,
- output[3:0] G,
- output[3:0] count,//模式一全屏显示计数
- output [7:0] seg,//7位数码管显示
- output vga_vs,//VGA行同步信号
- output vga_hs,//VGA列同步信号
- output [4:0] vga_r,//红色输出信号
- output [5:0] vga_g,//绿色输出信号
- output [4:0] vga_b //蓝色输出信号
- );
- //内部信号:模块内部的接口信号
-
- //wire [4:0] en_rgb_r;
- //wire [5:0] en_rgb_g;
- //wire [4:0] en_rgb_b;
- //模块例化
- vga vga( //接入分频时钟,限定显示的有效区域 ,将区域三等分
- .clk (clk),
- .button (button),
- .rst_n (rst_n),
- .vga_vs (vga_vs),
- .clkout_1s (clkout_1s),
- .vga_hs (vga_hs),
- .count (count),
- .vga_r (vga_r),
- .vga_g (vga_g),
- .vga_b (vga_b)
- );
-
- Nixie_Tube Nixie_Tube(//数码管显示部分
- .clk (clk),
- .button (button),
- .rst_n (rst_n),
- .count (count),
- .seg (seg),
- .G (G)
- );
- endmodule
- module vga( //显示分辨率为800 * 600 *72 MHZ
- //端口信号:模块的输入输出接口
- input clk, //连接至系统时钟,为50MHz
- input rst_n, //低电平复位
- input [1:0] button,//拨档开关选择显示模式
- output[4:0] vga_r,//颜色使能信号输出以及赋值
- output [5:0] vga_g,
- output [4:0] vga_b,
- output reg vga_hs,//VGA列同步信号
- output reg [3:0] count,//颜色序号计数
- output reg vga_vs,//VGA行同步信号
- output [2:0] en_rgb,//rRGB使能
- output reg clkout_1s //1s时钟,用于计数和数码管显示
- );
-
- //----------------VGA时序-----------------------------------
- // 显示模式 时钟
- // 800*600@72 50Mhz
- // 同步 后沿 有效 前沿 周期
- //hs 120 64 800 56 1040
- //vs 6 23 600 37 666
-
- //VGA显示相应参数
- parameter hy_all = 11'd1040, //列时序
- hy_a = 11'd120,
- hy_b = 11'd64,
- hy_c = 11'd800,
- hy_d = 11'd56,
-
- vy_all = 11'd666, //行时序
- vy_a = 11'd6,
- vy_b = 11'd23,
- vy_c = 11'd600,
- vy_d = 11'd37;
-
- //用计数器限定VGA显示相应区域,通过“行扫描,列填充”的方式
- reg [10:0] cnt_h,cnt_v;
-
- always@(posedge clk or posedge rst_n) //列计数
- if(rst_n)
- cnt_h <= 11'd0;
- else if(cnt_h == (hy_all-1))
- cnt_h <= 11'd0;
- else
- cnt_h <= cnt_h + 1'b1;
-
- always@(posedge clk or posedge rst_n)//在一列计数完之后将行加1
- if(rst_n)
- cnt_v <= 11'd0;
- else if(cnt_v == (vy_all-1))
- cnt_v <= 11'd0;
- else if(cnt_h ==(hy_all-1))
- cnt_v <= cnt_v + 1'b1;
-
- //限定列同步信号
- always @(posedge clk or posedge rst_n)
- if(rst_n)
- vga_hs <= 1'b1;
- else if(cnt_h ==(hy_all-1))
- vga_hs <= 1'b0;//同步信号低有效
- else if(cnt_h == hy_a)
- vga_hs <= 1'b1;
-
- //限定行同步信号
- always @(posedge clk or posedge rst_n)
- if(rst_n)
- vga_vs <= 1'b0;
- else if(cnt_v ==(vy_all-1))
- vga_vs <= 1'b0;
- else if(cnt_v == vy_a)
- vga_vs <= 1'b1;
-
-
- reg [31:0] cnt_1s;
-
- always @(posedge clk or posedge rst_n)//1s分频
- if (rst_n)
- cnt_1s <= 0;
- else
- begin
- if (cnt_1s == 32'd2500_0000-1)
- begin
- cnt_1s <= 0;
- clkout_1s <= ~clkout_1s; // 每过 0.5s 就反转时钟信号,1s信号
- end
- else
- begin
- cnt_1s <= cnt_1s + 1; // 计数器增加
- end
- end
- //计数模块
- always @(posedge clkout_1s or posedge rst_n)
- begin
- if(rst_n)
- begin
- count<=0;
- end
- else
- begin
- if(button==2'b00)
- begin
- if(count<=7)
- count<=count+1;
- else
- count<=0;
- end
- else
- begin count<=0;end
- end
- end
-
-
- reg [4:0]reg_enr;
- reg [5:0]reg_eng;
- reg [4:0]reg_enb;
-
- always @(posedge clk or posedge rst_n)
- begin
- if(rst_n)
- begin reg_enr=5'b11111;reg_eng=6'b111111;reg_enb=5'b11111;end
- else
- begin
- if(button==2'b00)
- begin//全屏显示
- case(count)
- 0:begin reg_enr <=5'b00000;reg_eng <=6'b000000;reg_enb <=5'b11111;end
- 1:begin reg_enr <=5'b00000;reg_eng <=6'b111111;reg_enb <=5'b00000;end
- 2:begin reg_enr <=5'b00000;reg_eng <=6'b111111;reg_enb <=5'b11111;end
- 3:begin reg_enr <=5'b11111;reg_eng <=6'b000000;reg_enb <=5'b00000;end
- 4:begin reg_enr <=5'b11111;reg_eng <=6'b000000;reg_enb <=5'b11111;end
- 5:begin reg_enr <=5'b11111;reg_eng <=6'b111111;reg_enb <=5'b00000;end
- 6:begin reg_enr <=5'b11111;reg_eng <=6'b111111;reg_enb <=5'b11111;end
- 7:begin reg_enr <=5'b11100;reg_eng <=6'b111000;reg_enb <=5'b00000;end
- default:begin reg_enr <=5'b10111;reg_eng <=6'b100111;reg_enb <=5'b10111;end
- endcase
- end
- else if(button==2'b01)//横屏显示
- begin
- if(cnt_v > 28 && cnt_v <= 28 + 10'd150) begin reg_enr <=5'b00000;reg_eng <=6'b000000;reg_enb <=5'b11111;end
- else if(cnt_v > 28 + 10'd150 && cnt_v <= 28 + 10'd300) begin reg_enr <=5'b00000;reg_eng <=6'b111111;reg_enb <=5'b00000;end
- else if(cnt_v > 28 + 10'd300 && cnt_v <= 28 + 10'd450) begin reg_enr <=5'b11111;reg_eng <=6'b000000;reg_enb <=5'b00000;end
- else if(cnt_v > 28 + 10'd450 && cnt_v <= 28 + 10'd600) begin reg_enr <=5'b11111;reg_eng <=6'b111111;reg_enb <=5'b11000;end
- end
- else if(button==2'b10)//竖屏显示
- begin
- if(cnt_h > 183 && cnt_h <= 183 + 10'd200) begin reg_enr <=5'b11111;reg_eng <=6'b000000;reg_enb <=5'b11111;end
- else if(cnt_h > 183 + 10'd200 && cnt_h <= 183 + 10'd400) begin reg_enr <=5'b11111;reg_eng <=6'b111111;reg_enb <=5'b00000;end
- else if(cnt_h > 183 + 10'd400 && cnt_h <= 183 + 10'd600) begin reg_enr <=5'b11111;reg_eng <=6'b111111;reg_enb <=5'b11111;end
- else if(cnt_h > 183 + 10'd600 && cnt_h <= 183 + 10'd800) begin reg_enr <=5'b10100;reg_eng <=6'b111000;reg_enb <=5'b00110;end
- end
- else if(button==2'b11)
- begin
- if((cnt_v > 28 && cnt_v <= 28 + 10'd150)&&(cnt_h > 183 && cnt_h <= 183 + 10'd200)
- ||(cnt_v > 28+10'd150 && cnt_v <= 28 + 10'd300)&&(cnt_h > 183+ 10'd200&& cnt_h <= 183 + 10'd400)
- ||(cnt_v > 28+10'd300 && cnt_v <= 28 + 10'd450)&&(cnt_h > 183+ 10'd400&& cnt_h <= 183 + 10'd600)
- ||(cnt_v > 28+10'd450 && cnt_v <= 28 + 10'd600)&&(cnt_h > 183+ 10'd600&& cnt_h <= 183 + 10'd800))
- //(cnt_v >= vy_a+ vy_b && cnt_v <= vy_a + vy_b + 10'd200列范围)&&(cnt_h >= hy_a + hy_b+ 10'd600行范围&& cnt_h <= hy_a + hy_b + 10'd800)
- begin
- reg_enr <=5'b00000;
- reg_eng <=6'b000000;
- reg_enb <=5'b11111;
- end
- else if((cnt_v > 28 && cnt_v <= 28 + 10'd150)&&(cnt_h > 183+10'd600 && cnt_h <= 183 + 10'd800)
- ||(cnt_v > 28+10'd150 && cnt_v <= 28 + 10'd300)&&(cnt_h > 183+ 10'd400&& cnt_h <= 183 + 10'd600)
- ||(cnt_v > 28+10'd300 && cnt_v <= 28 + 10'd450)&&(cnt_h > 183+ 10'd200&& cnt_h <= 183 + 10'd400)
- ||(cnt_v > 28+10'd450 && cnt_v <= 28 + 10'd600)&&(cnt_h > 183&& cnt_h <= 183 + 10'd200))
- begin
- reg_enr <=5'b11100;
- reg_eng <=6'b011100;
- reg_enb <=5'b10101;
- end
- else if((cnt_v > 28 && cnt_v <= 28 + 10'd150)&&(cnt_h > 183+10'd200 && cnt_h <= 183 + 10'd400)
- ||(cnt_v > 28+10'd150 && cnt_v <= 28 + 10'd300)&&(cnt_h > 183&& cnt_h <= 183 + 10'd200)
- ||(cnt_v > 28+10'd300 && cnt_v <= 28 + 10'd450)&&(cnt_h > 183+ 10'd600&& cnt_h <= 183 + 10'd800)
- ||(cnt_v > 28+10'd450 && cnt_v <= 28 + 10'd600)&&(cnt_h > 183+10'd400&& cnt_h <= 183 + 10'd600))
- begin
- reg_enr <=5'b00100;
- reg_eng <=6'b011010;
- reg_enb <=5'b00101;
- end
- else if((cnt_v > 28 && cnt_v <= 28 + 10'd150)&&(cnt_h > 183+10'd400 && cnt_h <= 183 + 10'd600)
- ||(cnt_v > 28+10'd150 && cnt_v <= 28 + 10'd300)&&(cnt_h > 183+ 10'd600&& cnt_h <= 183 + 10'd800)
- ||(cnt_v > 28+10'd300 && cnt_v <= 28 + 10'd450)&&(cnt_h > 183&& cnt_h <= 183 + 10'd200)
- ||(cnt_v > 28+10'd450 && cnt_v <= 28 + 10'd600)&&(cnt_h > 183+10'd200&& cnt_h <= 183 + 10'd400))
- begin
- reg_enr <=5'b10101;
- reg_eng <=6'b111110;
- reg_enb <=5'b10101;
- end
- end
- end
- end
- //rgb使能
- assign vga_r=reg_enr;//将寄存器值赋给颜色数据传输线
- assign vga_g=reg_eng;
- assign vga_b=reg_enb;
- endmodule
- module Nixie_Tube(
- input clk,
- input[1:0]button,
- input rst_n,
- input[3:0]count,
- output reg [7:0]seg,//7位数码管显示
- output reg[3:0] G//数码管使能
- );
-
- reg[31:0]cnt_1ms,clkout_1ms;
-
- //1ms时钟信号
- always @ (posedge clk)
- if(cnt_1ms==49999)
- cnt_1ms<=0;
- else
- cnt_1ms<=cnt_1ms+1;
-
- always @ (posedge clk)
- if(cnt_1ms<=24999)
- clkout_1ms<=0;
- else
- clkout_1ms<=1;
-
-
- reg [2:0]cnt_clkout_1ms;
-
-
- always @ (posedge clkout_1ms)
- begin
- if (cnt_clkout_1ms==3)
- cnt_clkout_1ms <=0;
- else
- cnt_clkout_1ms <= cnt_clkout_1ms + 1;
- end
- reg [3:0]qout;
-
-
- always @ (posedge clkout_1ms)
- begin
- if(button==2'b00)
- case(cnt_clkout_1ms)
- 0:begin
- qout <= count;
- G <= 4'b1110;
- end
- 1:begin
- qout <= 1'b0;
- G <= 4'b1101;
- end
- 2:begin
- qout <= button/2;
- G <= 4'b1011;
- end
- 3:begin
- qout <= button%2;
- G <= 4'b0111;
- end
- endcase
- else
- begin
- case(cnt_clkout_1ms)
- 0:begin
- qout <= 4'd9;
- G <= 4'b1110;
- end
- 1:begin
- qout <= 4'd9;
- G <= 4'b1101;
- end
- 2:begin
- qout <= button/2;
- G <= 4'b1011;
- end
- 3:begin
- qout <= button%2;
- G <= 4'b0111;
- end
- endcase
- end
-
- end
-
-
- always @(*)
- begin
- case(qout)
- 1:begin seg = 8'b01100000;end//1
- 2:begin seg = 8'b11011010;end//2
- 3:begin seg = 8'b11110010;end//3
- 4:begin seg = 8'b01100110;end//4
- 5:begin seg = 8'b10110110;end//5
- 6:begin seg = 8'b10111110;end//6
- 7:begin seg = 8'b11100000;end//7
- 8:begin seg = 8'b11111110;end//8
- 9:begin seg = 8'b00000010;end//-
- default:begin seg = 8'b11111100;end//0
- endcase
- end
- endmodule
- `timescale 1 ns/ 1 ns
- module VGA4_vlg_tst();
- reg [1:0] button;
- reg clk;
- reg rst_n;
- wire [3:0] G;
- wire clkout_1s;
- wire [3:0] count;
- wire [7:0] seg;
- wire [4:0] vga_b;
- wire [5:0] vga_g;
- wire vga_hs;
- wire [4:0] vga_r;
- wire vga_vs;
- VGA4 i1 (
- .G(G),
- .button(button),
- .clk(clk),
- .clkout_1s(clkout_1s),
- .count(count),
- .rst_n(rst_n),
- .seg(seg),
- .vga_b(vga_b),
- .vga_g(vga_g),
- .vga_hs(vga_hs),
- .vga_r(vga_r),
- .vga_vs(vga_vs)
- );
- initial
- begin
- rst_n=0
- clk=0;
- $display("Running testbench");
- end
- always
- begin
- #30
- clk=~clk;
- end
- endmodule
行时序和场时序仿真波形(深红色是因为没有给值,有需要的都者可以自行添加)
观察可以发现vga_vs低电平持续的时间为vga_hs的6个周期,这个的原理和不同VGA屏显示的时序有关
前两位数码管只有在拨档开关为00时才会正常计数计数内容为单色屏的序号否则为--
后两位数码管显示未拨档开关的状态值:button<=2'b00 单色屏 button<=2'b01 横屏显示 button<=2'b10 竖屏显示 button<=2'b11 棋盘格显示
问题一:count正常计数,数码管正常显示,但是单色屏不能正常显示它只会在极短的时间内闪八种不同的颜色
问题二:可以看到除了竖屏正常显示外,其他的颜色都为渐变色
这两个问题的原因我找了好久但是没有找出来,太痛苦了,希望有知道原因的读者可以不吝赐教,不胜感激
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。