三基色是指通过其他颜色的混合无法得到的“基本色”。由于人的肉眼有感知RGB(红绿蓝)三种不同颜色的锥体细胞,因此色彩空间通常可以由RGB三种基本色来表达。
. J& }0 b/ G" T$ D
自然界中的绝大部分彩色,都可以由三种基色按一定比例混合得到。
: x8 m& e3 j- \; f8 N
所以VGA接口中,表示颜色分量的只有红绿蓝三种基色。由于VGA接口的三基色为模拟信号值,FPGA无法输出,所以在FPGA的IO到VGA接口中间要有对应的数字量转模拟量的电路。
+ [6 q6 f$ s5 W: ]
SANXIN – B01中采用电阻网络来实现数字量转模拟量的功能。
9 R7 [* ]& c% j h' N
# V% L- H- J( t5 D
8 K. z. H5 }% W6 u! ~9 D7 Z
/ l) a6 E1 X5 O I B
# g: \% R" o5 `2 n- k3 {
; E2 V' q7 N A. T, @" _
图片在数字设备中,都是由像素点构成。
( E7 c& ?$ {+ B+ h8 m3 F
像素是指由图像的小方格组成的,这些小方块都有一个明确的位置和被分配的色彩数值,小方格颜色和位置就决定该图像所呈现出来的样子。可以将像素视为整个图像中不可分割的单位或者是元素。不可分割的意思是它不能够再切割成更小单位,它是以一个单一颜色的小格存在。每一个点阵图像包含了一定量的像素,这些像素决定图像在屏幕上所呈现的大小。
3 k1 R4 `$ c# w( a) n
VGA显示器上每一个像素点可以很多种颜色,由R、G、B三种颜色构成。如果每个像素点采用3位二进制数表示,即R用1bit表示,G用1bit表示,B用1bit表示,则此像素点一共可以显示8种颜色;如果每个像素点采用8位二进制数表示,即R用3bit表示,G用3bit表示,B用2bit表示,则此像素点一共可以显示256种颜色。在SANXIN – B01开发板中,采用RGB332的进行表示。
: ^$ _3 | h& X; N' }; N
在VGA显示器中,像素点RGB的二进制数越多,能够表示的颜色就越多,此时,显示的图像就会越清晰。
. ~4 q7 A- M5 m2 e5 f7 s4 }
在VGA显示器中,像素点的个数也是一个非常重要的一个指标。
0 K& \* _/ x+ _* _1 }+ A
我们可以打开自己电脑的显示分辨率。
# i$ R" w; X, Z6 i- r8 W5 G/ {
o( C( y7 ^" p2 ]8 Z6 k
! s, }" b- U: d
X( @! n5 Z- \, L
4 ~+ S) L* U* a7 ?$ M+ n/ I
- t3 ]0 g* B f$ ^2 r& \
分频率有各种模式,但是基本都是固定好的。分辨率都是长乘宽,前面的数为长,后面的数为宽。长表示屏幕横向可以有多少个像素点;宽表示屏幕纵向可以用多少个像素点。一般来说屏幕都是扁平的,所以长一般都会比宽大。
7 g8 `; R2 K* w
像素的多少不改变实际物理的尺寸大小,只是呈现的清晰度不同。可以对比500万像素的相机拍的图片和2000万像素的相机拍的图片,大小相同的情况下,清晰度是不同的。
1 N2 O) H6 `2 Z }$ o" w
只要我们按照显示器能够支持的分辨率的长和宽,将对应的像素点传输给VGA接口就可以了。但是VGA协议中,要求进行传输像素点的同时,还需要去传输一部分的同步信号。
" u2 \, r# D. q {6 I
显示器扫描方式分为逐行扫描和隔行扫描:逐行扫描是扫描从屏幕左上角一点开始,从左向右逐点扫描,每扫描完一行,电子束回到屏幕的左边下一行的起始位置,在这期间,每行结束时,用行同步信号进行同步;当扫描完所有的行,形成一帧,用场同步信号进行场同步,并使扫描回到屏幕左上方,开始下一帧。隔行扫描是指电子束扫描时每隔一行扫一线,完成一屏后在返回来扫描剩下的线,隔行扫描的显示器闪烁的厉害,会让使用者的眼睛疲劳。在此我们选择逐行扫描的方式。
- O+ w; x/ f0 S6 Z1 _& D
* \; d, x& Q3 n, M- i/ ~6 H* P
) V, E1 e9 I1 M
( R8 I9 o9 q. f/ ^
) W" s' j( @* ]7 `
4 a& S7 d4 d% ~, x0 V5 Q, w) ?$ f
VGA的时序主要包括行时序与场时序两个部分。其中行时序主要包括:行同步(Hor Sync) 、行消隐(Hor Back Porch) 、行视频有效(Hor Active Video)和行前肩(Hor Front Porch)这四个参数,行时序的时序图如下图所示:
1 C, i+ a- b$ r
" {0 z- X2 A& R0 J# f4 p% q
6 Q* |7 h) n- C# {) ~. n j9 k4 [% g. Q: S
' z9 h. t0 h J& c8 R( @; z. t. n
场时序主要包括:场同步(Ver Sync) 、场消隐(Ver Back Porch) 、场视频有效(Ver Active Video)和场前肩(Ver Front Porch)这四个参数,场时序的时序图如下图所示:
5 J2 j7 K7 I! e+ d( Z
( a# b7 I; @# h) \! V; F/ l$ a0 V; J
2 l$ q6 C* |9 [% @/ \
$ `# w+ V" P! K+ z8 K' D) M
* k$ E* F, n& [- Q. Q8 H
需要注意的有三点:
1、行时序是以”像素”为单位的, 场时序是以”行”为单位的。
2、VGA 工业标准显示模式要求:行同步,场同步都为负极性,即同步脉冲要求是负脉冲。
3、VGA 行时序对行同步时间、 消隐时间、 行视频有效时间和行前肩时间有特定的规范, 场时序也是如此。常用VGA 分辨率时序参数如下表所示:
( s# W( ~& h' P
( W2 {. j" n) _( W2 T+ F/ s* b$ r
& O$ t w. O' t) u8 t
- c0 U% ]6 f; g% y+ s/ z
5 {2 G) q. g+ U
本实验中选择640x480@60Hz。时钟的速率为25.175MHz,我们在设计时,时钟速率选择为25MHz 即可。
0 I$ T. F, _; _* l1 l& f' n$ g/ e6 n
- 设计要求+ \) q/ I2 o2 @! M& e. U( |1 Z! E
控制VGA显示器显示全屏红色或者其他颜色。
# F+ t# H$ b* n/ T0 z/ e4 |
- 设计分析2 C, k) f) g1 h3 S4 V
当我们选择640x480@60Hz的标准后,根据对应格式可以发现,此标准的一行为800个像素值,共有525行。也就是说并不是所有的像素值都可以显示出来,显示出来的只有中间的640列和480行,其他的像素值不显示(要求其他的像素值为黑色,即RGB全部给0)。
0 R2 N' @3 O: N1 m0 D2 t3 d; N
选择标准需要25MHz的时钟,我们可以选择使用锁相环来进行生成25MHz的时钟。
3 y# E# R V* `3 R4 C6 O/ D
扫描方式为逐行扫描,从左上角开始。定义一个列坐标计数器(cnt_hs),每个驱动时钟周期加1,当一行结束后,计数器也同时清零。一行为800个像素值,所以计数器将会在0到799无限循环。HSYNC信号在此计数器的前96的计数值拉低,其他时间拉高即可。
8 w, d5 B8 X+ x @1 I8 X
定义一个行坐标计数器(cnt_vs),扫描完一行后,进行加一,当一帧图片结束后,计数器清零。一行为800个像素值,所以等cnt_hs为799时,cnt_vs进行加一或者清零,由于一帧图片共有525行,所以计数器在0到524之间无限循环。VSYNC信号在此计数器的前两个计数器拉低,其他时间拉高即可。
2 e, C: K* ~1 \* I" y
根据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.
$ P! ?0 u( p& M
同时在两个有效显示区范围内,就可以显示出来。
( G8 q* |7 ?* |0 I. R
- 设计架构和信号说明
9 y$ m/ e5 e! l3 P1 c4 y9 S& m
此设计命名为vga_drive。
2 s( x8 I4 \' z- a! h. ?( k
- Z. j) ^" P9 `/ ~; t" \! G, Z7 b
* a( Q: {3 R7 `' G' b; L& [8 I2 }% W/ d
pll_vga为锁相环,利用外部输入的50MHz的时钟,产生VGA协议所需要的25MHz的时钟。
4 S# L2 _+ i& t0 v
vga_ctrl为VGA协议的驱动模块。
) Q( j) _1 U* { N8 R- b
: R8 S" X- [6 }: Q4 S' g0 w
/ p( v$ O8 a6 E6 L5 }0 m( v3 Z5 r% x4 T3 t E! ?4 m
0 u* L' `, o- J
- vga_ctrl设计实现
0 m) ~+ F* x8 V4 l
6 ?, L r0 y$ b' H2 G! M9 \
按照设计分析中的设计方法,进行设计即可。
3 N4 k, j( v) o, m
hs_en为列有效显示的表示信号;vs_en为行有效显示的表示信号。
0 H1 i) C7 J- g4 K- L" E1 G _4 \% h7 u( h
设计代码为:
" W0 i0 C* f" H: `/ X
. |0 q: ]- M& X# g1 `
8 Z# c( B8 e4 e% O& Z% \" |8 G
在设计中,给出的全屏颜色为红色。
2 I' i8 Z0 H! {& S1 x
- vga_drive设计实现
6 F+ G# }+ c& Q8 {& _. |
& Z/ w& r) g8 }: @8 r- s
调用锁相环,产生25MHz的时钟。
0 h# y* o* `2 o3 U' g
利用锁相环的输出锁定信号当作后续模块的复位信号使用。
. E6 @+ i& P7 ^4 m
设计代码为:
0 ~ f5 _0 |# Z E: T
+ ~$ R, b9 @: R* d
8 C& Z2 `% M+ e% w( S/ j
. X6 l, u- Q5 m1 ?3 k
仿真时只需要给出clk和rst_n的信号即可,在此不做介绍。设计者可以通过modelsim观看是否每一行输出640个红色值,以及是否每一帧输出480行。仿真时间较长,大约等待20ms,就可以仿真完一帧图像。
( ?' g+ L7 ~) a3 T! }9 K% d
4 T" W7 `) Y$ E8 W* X" x7 h( V
利用VGA线,将开发板的VGA接口和显示屏幕的VGA接口相连接,打开显示器。
# U2 b. q5 j5 b3 h* S
分配管脚,生成配置文件后,进行下板。
% X! |% b* L+ U t
红色全屏如下:
8 J; a3 L; A0 ~9 R/ m; W# B
+ J' [9 q0 L. m( D! p
, _" W$ ]' [& G! G2 W. p& F+ u; Z B7 p4 ~
- \: E. C/ ^6 w9 U- G6 V
. s. A; w: A, z& n
更改颜色为绿色,vga_rgb <= 8’b000_111_00,生成配置文件后,下板。
! A3 `/ d5 B, |3 X% W
绿色全屏为:
7 S1 M, u, h& W( Z
3 q* P' t! D! Q2 G
q. m1 l) _+ F% J! g5 g+ d2 j
' k7 h9 {( T" P: U( ^" ?
" I) | g6 L% w
3 X+ B" K/ A. l$ K
根据RGB332的排列,可以自由更改。不同的基色也可以进行混搭,进行验证。