定义
VGA(Video Graphics Array)视频图形阵列是IBM于1987年随PS/2机一起推出的一种使用模拟信号的视频传输标准,具有分辨率高、显示速率快、颜色丰富等优点,在彩色显示器领域得到了广泛的应用。不支持热插拔,不支持音频传输。VGA接口共有15针,分成3排,每排5个孔。提起这款接口,还要追溯到CRT时代。由于设计制造上的原因,CRT显示器只能接受模拟信号输入,最基本的包含R\G\B\H\V(分别为红、绿、蓝、行、场)5个分量,不管以何种类型的接口接入,其信号中至少包含以上这5个分量。
色彩原理
初中的时候我们就学过三基色,三基色是指通过其他颜色的混合无法得到的“基本色”,由于人的肉眼有感知红、绿、蓝三种不同颜色的锥体细胞,因此色彩空间通常可以由三种基本色来表达。这是色度学的最基本原理,即三基色原理。三种基色是相互独立的,任何一种基色都不能有其它两种颜色合成。红绿蓝是三基色,这三种颜色合成的颜色范围最为广泛。我们的RGB信号就是三基色的运用,对这三个信号赋予不同的数值,混合起来便是不同的色彩。
在RGB彩色模型中表示的图像由三个分量图像组成,每种原色一幅分量图像。利用MATLAB对图像进行读取,我们可以看到该图像RGB的数据为480*640*3 uint8,其中480*640表示长和宽的像素个数,3表示红绿蓝三个分量图像,uint8,表示每个分量图像(R、G、B)的像素点值的位宽为8比特,即可表示0-255的范围。
在设计RGB信号时,既可以R信号、G信号和B信号独立的赋值,最后连到端口上,也可以直接用RGB当做一个整体信号。RGB信号在使用时,其位宽有三种常见格式,如何配置,与我们选择的VGA解码芯片有关。此处实验笔者使用的 DE2-115 开发板采用 ADV7123 解码芯片,选用第三种格式,即RGB888格式。
显示器扫描方式分为逐行扫描和隔行扫描:逐行扫描是扫描从屏幕左上角一点开始,从左向右逐点扫描,每扫描完一行,电子束回到屏幕的左边下一行的起始位置,在这期间,CRT 对电子束进行消隐,每行结束时,用行同步信号进行同步;当扫描完所有的行,形成一帧,用场同步信号进行场同步,并使扫描回到屏幕左上方,同时进行场消隐,开始下一帧。隔行扫描是指电子束扫描时每隔一行扫一线,扫完一屏后再返回来扫描剩下的线,隔行扫描的显示器闪烁快速,可能会使使用者眼睛疲劳(本实验采用逐行扫描的方式)。
完成一行扫描的时间称为水平扫描时间,其倒数称为行频率;完成一帧(整屏)扫描的时间称为垂直扫描时间,其倒数称为场频率,即刷新一屏的频率,常见的有60Hz,75Hz等等。标准的VGA显示的场频60Hz,行频31.5KHz。
行场消隐信号:是针对老式显像管的成像扫描电路而言的。电子枪所发出的电子束从屏幕的左上角开始向右扫描,一行扫完需将电子束从右边移回到左边以便扫描第二行。在移动期间就必须有一个信号加到电路上,使得电子束不能发出。不然这个回扫线会破坏屏幕图像的。这个阻止回扫线产生的信号就叫作消隐信号,场信号的消隐也是一个道理。
显示带宽:带宽指的显示器可以处理的频率范围。如果是60Hz刷新频率的VGA,其带宽达640x480x60=18.4MHz,70Hz的刷新频率1024x768分辨率的SVGA,其带宽达1024x768x70=55.1MHz。
时钟频率:以640x480@59.94Hz(60Hz)为例,每场对应525个行周期(525=10+2+480+33),其中480为显示行。每场有场同步信号,该脉冲宽度为2个行周期的负脉冲,每显示行包括800点时钟,其中640点为有效显示区,每一行有一个行同步信号,该脉冲宽度为96个点时钟。由此可知:行频为525*59.94=31469Hz,需要点时钟频率:525*800*59.94约25MHz。
芯片驱动
笔者此次实验选用友晶 DE2-115 型号开发板,该型号开发板采用 ADV7123 数模转换芯片驱动VGA接口,在编写 VGA 接口驱动代码的之前,我们需要先看看 ADV7123 的 datasheet 了解其各个引脚的功能描述,然后对其进行相应的控制,从而更好的编写代码,下图为 AV7123 各个引脚功能描述
从上图中我们可以看到各个引脚的功能描述,然后再看电路的时候就更好的理解VGA 接口是如何驱动的,代码应该如何编写。
由此我们可以得知G0-G9,B0-B9,R0-R9是图像数据输入端口,连接到了FPGA;BLANK 为空白显示控制信号,低电平有效,故通常需要将其拉高,由 Verilog 代码实现; SYNC 为同步信号,低电平有效,通常情况下需要拉低,由 Verilog 代码实现; CLOCK 为芯片的时钟输入端,通常与像素刷新的频率保持一致;IOB, IOG,IOR为图像数据输出端,直接连到 VGA 接口处;HS,VS同步信号由 FPGA 对 VGA 接口直接控制驱动。
权电阻网络驱动
VGA数模转换电阻匹配网络分析_HXYDJ的博客-CSDN博客blog.csdn.net/qq_20222919/article/details/106380073
正点原子FPGA实战篇之VGA&RGB_哔哩哔哩_bilibiliwww.bilibili.com/video/BV1Ab411b7Dp
考虑到成本意识实现的简易方案,可用R-2R权电阻网络分流模拟DAC替ADV7123视频转换芯片。关于权电阻网络的具体原理参考上述B站视频,下面将列取两种使用权电阻网络进行数模转换的方案。该方案通常不需要 VGA_clk 和 VGA_blank 以及vga_sync 信号。
第一种:采用 RGB 565 格式
第二种:采用 RGB 332 格式
VGA 的接口的驱动时序,更据行、场同步信号的不同可分为四种模式。
对于上述的时序图可能有点难以理解,它是把行、场信号绘制在同一张图里,说明行、场信号的控制是相似的,只是时间参数不一样而已。具体的时序可参考下图。
上图中的字母都代表着不同点的像素值,其具体值可根据 VGA datasheet 查看。以640 * 480 @60HZ 为例,可见下图中高亮颜色的字体。此后就可以根据时序来编写代码了。
设计代码
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2021/09/18
// Design Name: X
// Module Name: vga_drive
// Project Name:
// Target Devices:
// Tool Versions:
// Description: VGA interface drive module , use ADV7123 to drive VGA interface
// DMT Video Timing Parameter Definitions - Negative H & Negative V Syncs
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module vga_drive
(
input wire clk , // vga clk : 25 MHZ
input wire rst_n , // system reset : low valid
input wire [23: 0] data_in , // input image data
output wire vga_hs , // VGA timing hsync
output wire vga_vs , // VGA timing vsync
output wire vga_clk , // VGA timing clk
output wire [10 : 0] hcount , // Horizon valid Pixels count 1-640 : used for instantiate
output wire [10 : 0] vcount , // Vertical valid Pixels count 1-480 : used for instantiate
output wire [23: 0] vga_data , // VGA data : used for instantiate
output wire vga_de , // active video flag : high valid
output wire vga_blank , // video control signals blank signal : low valid , usually set to high
output wire vga_sync // video control signals sync : low valid , usually set to low
);
reg [10 : 0] h_cnt ; // Horizon Pixels count : 1 - H_Total
reg [10 : 0] v_cnt ; // Vertical Pixels count : 1 - V_Total
wire hs_de ; // Horizonal active video : high valid
wire vs_de ; // vertical active video : high valid
//---------------------------------------------------------------------------------------------------//
// 640*480@60HZ pixel clock 25.175MHZ
//---------------------------------------------------------------------------------------------------//
parameter H_Total = 800 ;
parameter H_Sync = 96 ;
parameter H_Back_Porch = 40 ;
parameter H_Left_Border = 8 ;
parameter H_Active = 640 ;
parameter H_Right_Border = 8 ;
parameter H_Front_Porch = 8 ;
parameter H_Front = H_Sync + H_Back_Porch ; // the display of hsync front
parameter H_Start = H_Front + H_Left_Border ; // the begin of horizonal active video
parameter H_End = H_Start + H_Active ; // the end of horizonal active video
//---------------------------------------------------------------------------------------------------
parameter V_Total = 525 ;
parameter V_Sync = 2 ;
parameter V_Back_Porch = 25 ;
parameter V_Top_Border = 8 ;
parameter V_Active = 480 ;
parameter V_Bottom_Border = 8 ;
parameter V_Front_Porch = 2 ;
parameter V_Front = V_Sync + V_Back_Porch; // the display of hsync front
parameter V_Start = V_Front + V_Top_Border; // the begin of vertical active video
parameter V_End = V_Start + V_Active ; // the end of vertical active video
//====================================================================================================
//----------------------------vga_clk, vga_blank and vga_sync control --------------------------------
//====================================================================================================
assign vga_blank = 1'b1 ;
assign vga_sync = 1'b0 ;
assign vga_clk = clk ;
//====================================================================================================
//----------------------------------- HSYNC & VSYNC control -----------------------------------------
//====================================================================================================
assign vga_hs = (h_cnt <= H_Sync) ? 1'b0 : 1'b1 ; //1-96 vga_clk is low, 97-800 vga_clkl is high
assign vga_vs = (v_cnt <= V_Sync) ? 1'b0 : 1'b1 ; //1-2 vga_clk is low, 3-525 vga_clk is high
//====================================================================================================
//------------------------------------ H & V pixels count --------------------------------------------
//====================================================================================================
always @ (posedge clk or negedge rst_n)
begin
if(!rst_n)
h_cnt <= 11'b1 ;
else if(h_cnt == H_Total)
h_cnt <= 11'b1 ;
else
h_cnt <= h_cnt + 1'b1 ;
end
always @ (posedge clk or negedge rst_n)
begin
if(!rst_n)
v_cnt <= 11'b1 ;
else if(v_cnt == V_Total && h_cnt == H_Total)
v_cnt <= 11'b1 ;
else if(h_cnt == H_Total)
v_cnt <= v_cnt + 1'b1 ;
end
//====================================================================================================
//------------------------------ enable count: vga_de, hs_de, vs_de ----------------------------------
//====================================================================================================
assign hs_de = (h_cnt > H_Start && h_cnt <= H_End) ? 1'b1 : 1'b0 ;
assign vs_de = (v_cnt > V_Start && v_cnt <= V_End) ? 1'b1 : 1'b0 ;
assign vga_de = hs_de & vs_de ;
//====================================================================================================
//----------------------------------- active video pixels count --------------------------------------
//====================================================================================================
assign hcount = vga_de ? (h_cnt - H_Start) : 11'b0 ;
assign vcount = vga_de ? (v_cnt - V_Start) : 11'b0 ;
//====================================================================================================
//-------------------------------------- vga_data control --------------------------------------------
//====================================================================================================
assign vga_data = vga_de ? data_in : 24'b0 ;
endmodule
笔者在此处实验中遇到几个需要注意的问题。
第一:
在对行、场同步信号时序控制的过程中,使用 assign 语句赋值和 always 语句赋值是具有一个时钟差,故在对同步信号的控制中需要多加注意。两种赋值方式如下
第二:
行、场同步信号没有按照 datasheet 中的数值进行控制并不会影响显示器的驱动显示,但会导致显示器只能够显示一部分图像。
第三:
如果显示器没有被驱动需要检查数模转换芯片的所有引脚是否都赋予了相应的值。
协议--VGA - 咸鱼FPGA - 博客园www.cnblogs.com/xianyufpga/p/11128817.html
此文章也主要是用来记录自己的学习并分享给需要的同学,以上内容主要参考上述大佬的博客,以及网络上公开的各类学习记录,其出处在学习过程中已丢失,如上述文章涉及侵权,请告知,我会及时注明并删除
原网址: 访问
创建于: 2023-08-16 18:29:37
目录: default
标签: 无
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
最新评论