VGA模块实现详解

您所在的位置:网站首页 摄像头帧同步信号 VGA模块实现详解

VGA模块实现详解

2024-07-13 06:19| 来源: 网络整理| 查看: 265

VGA显示器工作原理

vga显示器显示图像,是采用电子枪逐行扫描的方式,在行场同步信号作用下,将构成图像的像素点从左到右,从上到下一点一点地显示在屏幕上,只要扫描速率够快,人眼看到的就是一整幅图像。下面结合行场同步信号进行讲解。

70b3521d54f4417eaf8aeb5cb18529da.png

行同步信号

b9b84cb5a473429a87da13a90970345c.png

行同步信号包含以下阶段:同步、后沿、左边框、有效图像、右边框、前沿

行同步信号的工作时钟周期为像素周期,也就是显示一个像素点所需要的时间。

行同步信号控制电子枪从左到右的扫描,当每扫描完一行后,电子枪指向显示器的最右端(不是屏幕的最右端,下面会解释),在同步脉冲的作用下,电子枪从最右端回到最左端,同步脉冲的持续时间就是电子枪返回所需要的时间,在这段时间电子枪处于关闭状态。电子枪返回最左端后,关闭状态需要持续一段时间才能开启扫描,这段时间称为后沿。开启扫描后,并不是立即扫描屏幕上的像素点,而是先要扫描经过一个左边框(想象一下以前台式电视机,这个左边框就是包裹着屏幕的物理边框),在经过左边框后电子枪就扫描到了屏幕上,这时可以输出有效图像了,在有效图像输出完毕后继续扫描经过一个右边框(也是物理边框)后电子枪会关闭(这时电子枪指向显示器最右端),从电子枪关闭到下一个同步脉冲之间的时间间隔称为前沿。在前沿、后沿、同步这3个阶段电子枪都是关闭的,用以实现消隐。

场同步信号

189f76c8cce547b1999a3dc6fb37f111.png

 场同步信号包含以下阶段:同步、后沿、上边框、有效图像、底边框、前沿

场同步信号的工作时钟周期是行扫描周期,也就是完成一行扫描所需要的时间。

场同步信号控制电子枪从上到下的扫描,每当一帧图像扫描完毕后,电子枪指向显示器的最下端,在同步脉冲的作用下,电子枪从最下端回到最上端,同步脉冲的持续时间就是电子枪返回所需要的时间,在这段时间电子枪处于关闭状态。电子枪返回最上端后,关闭状态需要持续一段时间才能开启扫描,这段时间称为后沿。开启扫描后,并不是立即扫描屏幕上的像素点,而是先要扫描经过一个上边框,在经过上边框后电子枪就扫描到了屏幕上,这时可以输出有效图像了,在有效图像输出完毕后继续扫描经过一个下边框后电子枪会关闭,从电子枪关闭到下一个同步脉冲之间的时间间隔称为前沿。在前沿、后沿、同步这3个阶段电子枪都是关闭的,用以实现消隐。

VGA565模块框图

af889dda1fac4fd7bef37208d35965f3.png

Clk_gen:锁相环模块,产生时钟

Vga_ctrl:vga控制模块,产生行场同步信号和坐标数据并传输行场同步信号和图像数据,坐标数据需要提前产生

Vga_pic:根据接收到的坐标经过1个像素时钟后输出数据

像素时钟计算

a670a02dd0d649bcb573dc6ebf0eb1bb.png

表1

采用640x480@60模式,像素时钟频率Vga_clk = 800x525x60 = 25200000 ≈25.175Mhz(误差忽略不计)

输入50Mhz,用锁相环2分频,输出25Mhz

一、vga_ctrl

先上我(火)哥的代码,慢慢拆析

module vga_ctrl ( input wire vga_clk , input wire sys_rst_n , input wire [15:0] pix_data , output wire [9:0] pix_x , output wire [9:0] pix_y , output wire hsync , output wire vsync , output wire [15:0] vga_rgb ); parameter H_SYNC = 10'd96 ,//同步 H_BACK = 10'd40 ,//后沿 H_LEFT = 10'd8 ,//左边框 H_VALID = 10'd640,//有效图像 H_RIGHT = 10'd8 ,//右边框 H_FRONT = 10'd8 ,//前沿 H_TOTAL = 10'd800;//同步+后沿+左边框+有效图像+右边框+前沿 parameter V_SYNC = 10'd2 ,//同步 V_BACK = 10'd25 ,//后沿 V_TOP = 10'd8 ,//上边框 V_VALID = 10'd480,//有效图像 V_BOTTOM= 10'd8 ,//底边框 V_FRONT = 10'd2 ,//前沿 V_TOTAL = 10'd525;//总共 reg [9:0] cnt_h ; reg [9:0] cnt_v ; wire pix_data_req; wire rgb_valid ; always@(posedge vga_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) cnt_h = V_SYNC + V_BACK + V_TOP) &&(cnt_v < V_SYNC + V_BACK + V_TOP + V_VALID)) ? 1'b1 : 1'b0;

在有效区间内,rgb_valid为高电平,其用来控制数据从输入到输出的传输,要求数据提前准备好

assign vga_rgb = (rgb_valid == 1'b1) ? pix_data : 16'h0000;

要提前准备数据,就要提前1个像素周期产生坐标信号,因为Vga_pic需要经过1个像素周期来生成数据。

像素坐标的生成:

ee3d6b95717948c18fe10ab57423b711.png  

a670a02dd0d649bcb573dc6ebf0eb1bb.png

表1

信号在有效区内输出坐标信号,在无效区内输出无效坐标信号(全1)以示无效。进入有效区内坐标从(0,0)开始计数。

若不提前产生坐标数据,根据表1,列坐标=行计数器-(同步+后沿+左边框) ;这点好理解,若同步+后沿+左边框=96+40+8=144,行计数器=144,那相减后为0,表示第0列。同理,行坐标=场计数器-(同步+后沿+上边框)。

若要提前产生坐标数据,重点在于操作行计数器。比如,对于640x480@60,若当前坐标为(1,1),那么下一个坐标就是(1,2),改变的是列,而行不变,若当前正在输出坐标(0,0)的数据,那么当前的坐标输出就应为(0,1),以通知Vga_pic模块提前准备好(0,1)的数据。若当前坐标为(0,639),下一个坐标就应为(1,0)。若当前坐标为(439,639),下一个坐标就应为(0,0)。那么如何提前产生像素坐标呢?

每切换一行,行计数器都是从0开始计数,行坐标不变,对应的列坐标从无效区逐渐计数进入有效区,可以将列坐标有效区向左平移一个像素周期,以提前产生像素坐标,如图1。

d88d96dca55f4e72b7d5da80513c7e13.png

图1 

此时的行有效区间:

cnt_h >= H_SYNC + H_BACK + H_LEFT-1

cnt_h < H_SYNC + H_BACK + H_LEFT + H_VALID-1

此时的场有效区间(不变):

cnt_v >= V_SYNC + V_BACK + V_TOP

cnt_v < V_SYNC + V_BACK + V_TOP + V_VALID

此时的有效坐标信号:

列坐标=行计数器-(同步+后沿+左边框-1)

行坐标=场计数器-(同步+后沿+上边框)

进入坐标有效区域内需要一个指示信号,在有效区内指示信号拉高

assign pix_data_req = ((cnt_h >= H_SYNC + H_BACK + H_LEFT - 1'b1) && (cnt_h < H_SYNC + H_BACK + H_LEFT + H_VALID - 1'b1) &&(cnt_v >= V_SYNC + V_BACK + V_TOP) &&(cnt_v < V_SYNC + V_BACK + V_TOP + V_VALID)) ? 1'b1 : 1'b0;

该指示信号用来控制坐标输出

assign pix_x = (pix_data_req == 1'b1) ? (cnt_h - (H_SYNC + H_BACK + H_LEFT - 1'b1)) : 10'h3ff; assign pix_y = (pix_data_req == 1'b1) ? (cnt_v - (V_SYNC + V_BACK + V_TOP)) : 10'h3ff;

至此,vga_ctrl讲解完毕。

二、vga_pic

该模块的功能就是根据输入的坐标数据经过一个像素时钟后输出对应坐标的图像数据,具体实现五花八门。若觉得一个像素周期时间太少,可修改vga_ctrl模块。

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3