三基色是指通过其他颜色的混合无法得到的“基本色”。由于人的肉眼有感知RGB(红绿蓝)三种不同颜色的锥体细胞,因此色彩空间通常可以由RGB三种基本色来表达。
! R: A# g7 J p" w
自然界中的绝大部分彩色,都可以由三种基色按一定比例混合得到。
% b$ r9 B! h: c6 w7 E
所以VGA接口中,表示颜色分量的只有红绿蓝三种基色。由于VGA接口的三基色为模拟信号值,FPGA无法输出,所以在FPGA的IO到VGA接口中间要有对应的数字量转模拟量的电路。
3 R, Z8 X/ _" g6 _$ L/ ?
SANXIN – B01中采用电阻网络来实现数字量转模拟量的功能。
( u1 u2 m( I* l1 E* w( R# B7 I4 I
( e' C3 e* v9 h4 o5 Q+ ]6 w
% } J$ `1 a9 ~0 }9 o# N& V
% ]6 z( C T' ]
- S) d0 T7 e5 B; @' }0 J$ L
: w7 i5 N, H( s" e; S% I
图片在数字设备中,都是由像素点构成。
4 L7 k3 k& y! \
像素是指由图像的小方格组成的,这些小方块都有一个明确的位置和被分配的色彩数值,小方格颜色和位置就决定该图像所呈现出来的样子。可以将像素视为整个图像中不可分割的单位或者是元素。不可分割的意思是它不能够再切割成更小单位,它是以一个单一颜色的小格存在。每一个点阵图像包含了一定量的像素,这些像素决定图像在屏幕上所呈现的大小。
( S2 a6 i$ a" h4 C4 ]# [
VGA显示器上每一个像素点可以很多种颜色,由R、G、B三种颜色构成。如果每个像素点采用3位二进制数表示,即R用1bit表示,G用1bit表示,B用1bit表示,则此像素点一共可以显示8种颜色;如果每个像素点采用8位二进制数表示,即R用3bit表示,G用3bit表示,B用2bit表示,则此像素点一共可以显示256种颜色。在SANXIN – B01开发板中,采用RGB332的进行表示。
! ?6 w" Q1 M: _5 d+ v+ S3 q
在VGA显示器中,像素点RGB的二进制数越多,能够表示的颜色就越多,此时,显示的图像就会越清晰。
6 q/ p$ N, X1 I0 |' A# t! k# n/ D; R! X" I
在VGA显示器中,像素点的个数也是一个非常重要的一个指标。
) m' \7 J, l) |0 X9 r! e
我们可以打开自己电脑的显示分辨率。
' _% L7 c% m! ]# j' c- Q
! v1 [ ~4 E+ z& Y, @
L3 w6 A2 D7 {/ q* Z' b0 T/ G
3 r+ E1 J( G; L- M
* x9 D/ Q& `' E5 M) l& |5 q
4 x% L' U* n. Y0 J9 h8 S9 t
分频率有各种模式,但是基本都是固定好的。分辨率都是长乘宽,前面的数为长,后面的数为宽。长表示屏幕横向可以有多少个像素点;宽表示屏幕纵向可以用多少个像素点。一般来说屏幕都是扁平的,所以长一般都会比宽大。
. H! Y5 f8 k4 ^4 r& s
像素的多少不改变实际物理的尺寸大小,只是呈现的清晰度不同。可以对比500万像素的相机拍的图片和2000万像素的相机拍的图片,大小相同的情况下,清晰度是不同的。
4 I" G% Z& A- h4 v8 d3 ?6 d# @
只要我们按照显示器能够支持的分辨率的长和宽,将对应的像素点传输给VGA接口就可以了。但是VGA协议中,要求进行传输像素点的同时,还需要去传输一部分的同步信号。
8 t! t) f" A- b# h
显示器扫描方式分为逐行扫描和隔行扫描:逐行扫描是扫描从屏幕左上角一点开始,从左向右逐点扫描,每扫描完一行,电子束回到屏幕的左边下一行的起始位置,在这期间,每行结束时,用行同步信号进行同步;当扫描完所有的行,形成一帧,用场同步信号进行场同步,并使扫描回到屏幕左上方,开始下一帧。隔行扫描是指电子束扫描时每隔一行扫一线,完成一屏后在返回来扫描剩下的线,隔行扫描的显示器闪烁的厉害,会让使用者的眼睛疲劳。在此我们选择逐行扫描的方式。
* V% {' S" ?" ~
( k0 M% M0 ~ P+ |2 E
" }! A7 `6 K# U' m: d/ J$ \5 w# ^5 X
, }% B# U% C' Y7 y
( d! b& t0 j& Z
7 w% }; Y. E3 ^* n
VGA的时序主要包括行时序与场时序两个部分。其中行时序主要包括:行同步(Hor Sync) 、行消隐(Hor Back Porch) 、行视频有效(Hor Active Video)和行前肩(Hor Front Porch)这四个参数,行时序的时序图如下图所示:
z# @" W. N/ x
' l8 o( Y9 M1 l. l* h
% q8 K/ p5 O! H
. D. t6 e8 ^/ e
2 t& g8 b, _3 {& a0 [0 |/ I4 U
场时序主要包括:场同步(Ver Sync) 、场消隐(Ver Back Porch) 、场视频有效(Ver Active Video)和场前肩(Ver Front Porch)这四个参数,场时序的时序图如下图所示:
3 C6 v8 i0 d! f" \% C/ \" M
. g% u, M; g/ V8 O
8 k! R4 |0 R# d2 ^0 L- r+ Y) k( s6 ^/ m( D* I
# u d* G, |* K, B$ x/ s% d# q
需要注意的有三点:
1、行时序是以”像素”为单位的, 场时序是以”行”为单位的。
2、VGA 工业标准显示模式要求:行同步,场同步都为负极性,即同步脉冲要求是负脉冲。
3、VGA 行时序对行同步时间、 消隐时间、 行视频有效时间和行前肩时间有特定的规范, 场时序也是如此。常用VGA 分辨率时序参数如下表所示:
# c3 x1 w$ q* ^% @3 {- f! Q
4 `# }' S( l) Y8 J" I5 ?/ a
1 K& ~! K9 b/ v" o# ~8 H9 ?
0 y' u& b% M8 Q
/ \( N$ O; C+ b$ T: D$ z- E# }$ w
本实验中选择640x480@60Hz。时钟的速率为25.175MHz,我们在设计时,时钟速率选择为25MHz 即可。
% B5 O9 z }: d: C/ P
- 设计要求
% Q& G' u% L) N& E$ y
控制VGA显示器显示全屏红色或者其他颜色。
, m8 e7 {- b6 |3 u" n, J1 s
- 设计分析/ k/ ?8 M5 A" q3 g$ _
当我们选择640x480@60Hz的标准后,根据对应格式可以发现,此标准的一行为800个像素值,共有525行。也就是说并不是所有的像素值都可以显示出来,显示出来的只有中间的640列和480行,其他的像素值不显示(要求其他的像素值为黑色,即RGB全部给0)。
* l4 u1 P& r% Q; V' k
选择标准需要25MHz的时钟,我们可以选择使用锁相环来进行生成25MHz的时钟。
( s+ b" |7 R" E9 x7 l$ B4 N
扫描方式为逐行扫描,从左上角开始。定义一个列坐标计数器(cnt_hs),每个驱动时钟周期加1,当一行结束后,计数器也同时清零。一行为800个像素值,所以计数器将会在0到799无限循环。HSYNC信号在此计数器的前96的计数值拉低,其他时间拉高即可。
! H3 P6 e4 u% ~3 ]. O
定义一个行坐标计数器(cnt_vs),扫描完一行后,进行加一,当一帧图片结束后,计数器清零。一行为800个像素值,所以等cnt_hs为799时,cnt_vs进行加一或者清零,由于一帧图片共有525行,所以计数器在0到524之间无限循环。VSYNC信号在此计数器的前两个计数器拉低,其他时间拉高即可。
$ R4 V% }6 s# t8 A3 A1 w# B
根据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.
4 ?" ]* k- j, W& X8 S8 V8 G
同时在两个有效显示区范围内,就可以显示出来。
* ]6 X- |) Z8 w) {! e% J- E
- 设计架构和信号说明
) ~9 v! G& v \ E5 f
此设计命名为vga_drive。
/ G: j9 _) j9 l6 t
# I6 X' N9 n. Y+ _9 N5 C# B$ z
" w8 E/ {" C; b( \' p
# @. S0 v" g3 O$ z6 E6 L
pll_vga为锁相环,利用外部输入的50MHz的时钟,产生VGA协议所需要的25MHz的时钟。
% c9 l- @* ]; p' U: O( W2 S6 n5 Y
vga_ctrl为VGA协议的驱动模块。
8 s6 m+ M2 p) E8 r z f- z9 z7 Q
* T J1 W/ E5 T' a% z! x( k
1 A8 M. R; \; C/ y; ~0 V# a
+ @" Y0 G A4 S1 b6 c$ z
' R/ K) D" N2 l8 P
- vga_ctrl设计实现
8 y6 F6 [' K9 n1 b* d _- y7 ~/ f
# H9 M6 s; X# X8 r$ ?2 z8 ~
按照设计分析中的设计方法,进行设计即可。
/ y( A( G: l- ]' \1 V# ?) e
hs_en为列有效显示的表示信号;vs_en为行有效显示的表示信号。
* |2 r, ~3 F& R9 }2 J* ~
设计代码为:
2 {- W6 Y) U: ]5 V8 O4 _
4 f2 H+ ]3 |) S1 n
. r" ^. J1 v0 A8 U
在设计中,给出的全屏颜色为红色。
% b; \( ^, ^' h. v; y: q) v' w; u% P7 f
- vga_drive设计实现
0 s1 r: ?/ d% Q& B
. s* f! T4 r5 O
调用锁相环,产生25MHz的时钟。
) E( E6 r' E/ ]/ ]6 J/ R
利用锁相环的输出锁定信号当作后续模块的复位信号使用。
7 o% G0 _- G5 F- |6 R* C% s/ S: v
设计代码为:
- J u g8 g5 J5 r$ b. y3 D( G% U
4 G N S8 I9 n& o: x4 J$ h
" Q3 h* H) w* c" h* j4 h$ k( k
, n* r) S! n1 D- m; C: p& L; l
仿真时只需要给出clk和rst_n的信号即可,在此不做介绍。设计者可以通过modelsim观看是否每一行输出640个红色值,以及是否每一帧输出480行。仿真时间较长,大约等待20ms,就可以仿真完一帧图像。
8 L2 U8 R! B: \+ F" C
- 板级测试' g2 k$ g: e# n4 v* m
, V+ u2 I" _/ K
利用VGA线,将开发板的VGA接口和显示屏幕的VGA接口相连接,打开显示器。
3 P. Q# A/ y6 ]
分配管脚,生成配置文件后,进行下板。
& q- p, U( T) V N' D8 X/ H2 g. a2 `
红色全屏如下:
# P, w# h3 n# V- y
) l) {2 m( g; ~3 w, m
4 q( V& G5 Y" l$ I" S6 m- M) _. p& U
7 g1 x: D+ v, {6 w3 |; m# A, A
8 h" s: w. p7 F6 D; O- ?2 g& K4 N
更改颜色为绿色,vga_rgb <= 8’b000_111_00,生成配置文件后,下板。
- D; U; |7 _9 g9 p1 U
绿色全屏为:
6 _) f# L5 V$ Y; {* C# I
O! v4 i, J& t
( d+ U) O9 D; w; {- B) u1 o9 U
# k) s7 b. ?; E* y! {
# \/ q, N2 N6 N8 w4 Q8 a
9 n9 f9 {7 E5 ]
根据RGB332的排列,可以自由更改。不同的基色也可以进行混搭,进行验证。