三基色是指通过其他颜色的混合无法得到的“基本色”。由于人的肉眼有感知RGB(红绿蓝)三种不同颜色的锥体细胞,因此色彩空间通常可以由RGB三种基本色来表达。
. ?, Z, }; Q* G6 P& T- F
自然界中的绝大部分彩色,都可以由三种基色按一定比例混合得到。
% s5 q A) c4 V1 |
所以VGA接口中,表示颜色分量的只有红绿蓝三种基色。由于VGA接口的三基色为模拟信号值,FPGA无法输出,所以在FPGA的IO到VGA接口中间要有对应的数字量转模拟量的电路。
2 n( K7 L0 r) @7 J/ L7 C
SANXIN – B01中采用电阻网络来实现数字量转模拟量的功能。
% t2 t& }( K7 Q& k
8 L7 L d8 {" Y' \1 \7 Z
4 ^* S$ t( m3 V( L
" T1 R/ T: \% q7 R& Y' ]
3 c" L6 u) E5 t# e' G' f8 S; I- z% X7 q
" j& e3 C2 n, d3 ]% T( ?
图片在数字设备中,都是由像素点构成。
5 ^; b) K& }; E G
像素是指由图像的小方格组成的,这些小方块都有一个明确的位置和被分配的色彩数值,小方格颜色和位置就决定该图像所呈现出来的样子。可以将像素视为整个图像中不可分割的单位或者是元素。不可分割的意思是它不能够再切割成更小单位,它是以一个单一颜色的小格存在。每一个点阵图像包含了一定量的像素,这些像素决定图像在屏幕上所呈现的大小。
7 w% L- X- d+ |) Q# w$ f; h
VGA显示器上每一个像素点可以很多种颜色,由R、G、B三种颜色构成。如果每个像素点采用3位二进制数表示,即R用1bit表示,G用1bit表示,B用1bit表示,则此像素点一共可以显示8种颜色;如果每个像素点采用8位二进制数表示,即R用3bit表示,G用3bit表示,B用2bit表示,则此像素点一共可以显示256种颜色。在SANXIN – B01开发板中,采用RGB332的进行表示。
& W; Z8 y7 T/ l! T4 }4 z. Z
在VGA显示器中,像素点RGB的二进制数越多,能够表示的颜色就越多,此时,显示的图像就会越清晰。
5 H1 H3 a j# |9 m$ F! l
在VGA显示器中,像素点的个数也是一个非常重要的一个指标。
3 U! p2 w' l& P, h" Z
我们可以打开自己电脑的显示分辨率。
. |" K4 R# `' U/ Y
& A1 s" u1 `9 k# M- g, o" h* I4 ^
. X1 t3 K7 z8 ~; Y/ h% k' K+ W% A
R( ?/ t1 ^1 G% n5 D* r) l5 w m* g8 T- o# x" Z
; G: G! G0 A0 y7 Z
分频率有各种模式,但是基本都是固定好的。分辨率都是长乘宽,前面的数为长,后面的数为宽。长表示屏幕横向可以有多少个像素点;宽表示屏幕纵向可以用多少个像素点。一般来说屏幕都是扁平的,所以长一般都会比宽大。
; }0 s7 ?; l* ]. h
像素的多少不改变实际物理的尺寸大小,只是呈现的清晰度不同。可以对比500万像素的相机拍的图片和2000万像素的相机拍的图片,大小相同的情况下,清晰度是不同的。
4 @; z3 [* C, f
只要我们按照显示器能够支持的分辨率的长和宽,将对应的像素点传输给VGA接口就可以了。但是VGA协议中,要求进行传输像素点的同时,还需要去传输一部分的同步信号。
* u6 I! _9 W/ Y
显示器扫描方式分为逐行扫描和隔行扫描:逐行扫描是扫描从屏幕左上角一点开始,从左向右逐点扫描,每扫描完一行,电子束回到屏幕的左边下一行的起始位置,在这期间,每行结束时,用行同步信号进行同步;当扫描完所有的行,形成一帧,用场同步信号进行场同步,并使扫描回到屏幕左上方,开始下一帧。隔行扫描是指电子束扫描时每隔一行扫一线,完成一屏后在返回来扫描剩下的线,隔行扫描的显示器闪烁的厉害,会让使用者的眼睛疲劳。在此我们选择逐行扫描的方式。
: m T% g7 z* z' ]9 @( |
0 k/ v$ \$ z& R c" f% V6 E& }) p1 j' p
3 G1 c) I) w/ f
8 j$ {$ `% A4 U# b
) h3 B7 A0 h0 _! j4 K$ M1 r! D- {
# G" S/ L( p2 f1 ~
VGA的时序主要包括行时序与场时序两个部分。其中行时序主要包括:行同步(Hor Sync) 、行消隐(Hor Back Porch) 、行视频有效(Hor Active Video)和行前肩(Hor Front Porch)这四个参数,行时序的时序图如下图所示:
& V; Y x" c. ?' L
9 h) P, H4 n/ z1 m' ~
- g3 M: \# p( A2 j! I5 {4 K
5 |# u) a$ @6 M* j' K7 Y
! Z8 ] U7 m# p8 Y+ T6 Y% R2 q
场时序主要包括:场同步(Ver Sync) 、场消隐(Ver Back Porch) 、场视频有效(Ver Active Video)和场前肩(Ver Front Porch)这四个参数,场时序的时序图如下图所示:
+ l. i% x8 [/ Y
; ?$ B- S( C& T+ b
1 z7 \* ]5 o: n" A1 C; b3 {! w4 `4 Z9 E# F# S% R, q
0 C/ }3 y- H. U0 H
需要注意的有三点:
1、行时序是以”像素”为单位的, 场时序是以”行”为单位的。
2、VGA 工业标准显示模式要求:行同步,场同步都为负极性,即同步脉冲要求是负脉冲。
3、VGA 行时序对行同步时间、 消隐时间、 行视频有效时间和行前肩时间有特定的规范, 场时序也是如此。常用VGA 分辨率时序参数如下表所示:
, S; i6 S! M, ?1 Y, v! g$ n2 q
3 V% x b9 S, N$ b# H% X: U& r; O
: U% w- {) y2 z
% X- n+ @# U; T! G2 \
N% C% n0 t" w" |& ?) I0 a
本实验中选择640x480@60Hz。时钟的速率为25.175MHz,我们在设计时,时钟速率选择为25MHz 即可。
+ ?& r# O7 }* ?5 T( F! Y) A
- 设计要求8 z2 ?; M0 a3 f- H6 b& A
控制VGA显示器显示全屏红色或者其他颜色。
9 j3 n; n& w/ {6 h
- 设计分析
$ Z' ?6 |5 [: _. U$ [( I% v1 R
当我们选择640x480@60Hz的标准后,根据对应格式可以发现,此标准的一行为800个像素值,共有525行。也就是说并不是所有的像素值都可以显示出来,显示出来的只有中间的640列和480行,其他的像素值不显示(要求其他的像素值为黑色,即RGB全部给0)。
/ R$ j* O- V# A7 P' H c
选择标准需要25MHz的时钟,我们可以选择使用锁相环来进行生成25MHz的时钟。
2 u1 ]1 w& @6 b( T& G' e
扫描方式为逐行扫描,从左上角开始。定义一个列坐标计数器(cnt_hs),每个驱动时钟周期加1,当一行结束后,计数器也同时清零。一行为800个像素值,所以计数器将会在0到799无限循环。HSYNC信号在此计数器的前96的计数值拉低,其他时间拉高即可。
0 X6 ^; R' P% u0 _* M# Z; K
定义一个行坐标计数器(cnt_vs),扫描完一行后,进行加一,当一帧图片结束后,计数器清零。一行为800个像素值,所以等cnt_hs为799时,cnt_vs进行加一或者清零,由于一帧图片共有525行,所以计数器在0到524之间无限循环。VSYNC信号在此计数器的前两个计数器拉低,其他时间拉高即可。
0 G0 n6 a, w3 q9 y* `( Q7 k
根据cnt_hs和cnt_vs,按照对应的标准,就可以得出显示的640列和480行的具体位置。
列显示的范围为:hs_a+hs_b+hs_c>cnt_hs>hs_a+hs_b-1.
行显示的范围为:vs_f+vs_g+vs_h>cnt_vs>vs_f+vs_g-1.
" K: Z5 _0 F J& g5 X; E
同时在两个有效显示区范围内,就可以显示出来。
3 W2 u" k) h) L& P
- 设计架构和信号说明
" k0 E' R2 m) R- @
此设计命名为vga_drive。
3 Z, ]5 k( V+ V
2 m; y6 l- e1 f/ `
5 v1 n" M( }; Y% X
9 G& M& r0 F' A+ |3 y2 D$ R" G
pll_vga为锁相环,利用外部输入的50MHz的时钟,产生VGA协议所需要的25MHz的时钟。
. r, A- ~+ T6 l% m8 o' O: z: K
vga_ctrl为VGA协议的驱动模块。
0 B+ c( y; F: B% m, ?
* N1 a$ u3 C) k
j1 J& M9 C- Y; v: B
; P* W( x4 \* |# p# F
3 z2 s$ M% s2 X# i- \$ M
- vga_ctrl设计实现! P. }8 T7 @5 q& z" e; E2 A
m& h, @4 q7 z/ h+ W- O5 K
按照设计分析中的设计方法,进行设计即可。
* K- B: B! u* t, i& i
hs_en为列有效显示的表示信号;vs_en为行有效显示的表示信号。
" c4 b3 y7 r# P# h( o/ m8 E& y
设计代码为:
2 W3 b1 A- q0 m9 z" o
/ t* @* Y) Y2 P s
4 o P3 ]+ j2 s! L( A1 H0 N0 ?8 C
在设计中,给出的全屏颜色为红色。
( y* w" l9 ]. s5 t$ B- Y4 ?
- vga_drive设计实现* [! v7 j; I) z$ z( N/ q
1 n* P6 d- T0 H! r" c5 [: e! _
调用锁相环,产生25MHz的时钟。
0 L# l% N) r" E/ i5 y
利用锁相环的输出锁定信号当作后续模块的复位信号使用。
$ `* _9 B8 I" @1 z8 J! T
设计代码为:
. k1 F+ R2 K& {, {
8 F4 r) o6 a) B# t3 Z8 Z
5 c. K5 s0 k+ d; x v
8 G! A6 g% U6 A9 ?8 s
仿真时只需要给出clk和rst_n的信号即可,在此不做介绍。设计者可以通过modelsim观看是否每一行输出640个红色值,以及是否每一帧输出480行。仿真时间较长,大约等待20ms,就可以仿真完一帧图像。
7 l; K8 p2 f6 h9 f, U% J
w: T2 e5 M; M1 g
利用VGA线,将开发板的VGA接口和显示屏幕的VGA接口相连接,打开显示器。
& |& W3 b; |. U& Q9 @
分配管脚,生成配置文件后,进行下板。
$ g; _. [; t R% A3 ~! M3 J* |0 q
红色全屏如下:
5 M* \1 [$ y/ N4 a
; L2 E6 k6 {5 Y' Z* m o. O
2 Y( A6 t0 M" X$ r2 L
4 g0 |! _1 u# L' E7 u( v& b* H8 b
8 v6 d- E; ?% o" D
# E9 c. i$ X# z
更改颜色为绿色,vga_rgb <= 8’b000_111_00,生成配置文件后,下板。
+ A0 \4 `; ~2 f6 A
绿色全屏为:
8 q$ r* p$ p, U+ [
- N6 u6 `/ R/ S2 K* k8 Q, m1 l5 m2 P
4 f W$ ]* M; S n
X2 {3 G! X1 Y/ `# I
# y% c, v4 C# \( r
4 N' }( u( K# j* ]" G2 X
根据RGB332的排列,可以自由更改。不同的基色也可以进行混搭,进行验证。