"); //-->
基于FPGA的VGA显示矩形框_VGA接口设计
明德扬科技教育有限公司
官网:www.mdy-edu.com
淘宝:mdy-edu.taobao.com
QQ群:544453837
QQ咨询:158063679
VGA显示矩形
1 功能概述
VGA(Video Graphics Array,即显示绘图阵列)接口,就是显卡上输出模拟信号的接口,也叫D-Sub接口。VGA接口作为一种视频传输标准,在当时具有分辨率高、显示速率快、颜色丰富等优点,在彩色显示器领域得到了广泛的应用。VGA接口自IBM 在 1987 年随 PS/2 机一起推出以来,成为电脑显卡上应用最为广泛的接口类型,绝大多数的显卡都带有此种接口。
VGA类型的显示驱动需要比较高的扫面频率和尽量短的处理时间,因而通过FPGA来实现VGA显示的驱动和控制非常有效。在FPGA中,使用少量的资源即可产生VGA各种信号,利用FPGA完成的VGA显示控制,可以使图像显示脱离PC机的控制,形成体积小、功耗低的嵌入式格式。将该模式扩展运用到便携式或者手持式设备中,更是具备实际运用价值。
本案例在分辨率640*480,帧长800*525的VGA接口的显示屏中,运用FPGA实现矩形图像,作为整个采集系统显示的参考,具备极大的实用价值。具体功能要求:
本项目要求如下:
(1)该VGA接口输出的图像分辨率为下列表格中第一种640*480,即帧长为800*525。
(2)依次完成以下图像显示:在显示屏边缘上显示一个红色边框(边框宽为20像素),在屏幕的中央显示一个绿色矩形(矩形长为150像素,高为100像素)。
图1 显示图像要求
2 设计思路
VGA显示中,FPGA需要产生5个信号:R、G、B三基色信号,行同步信号HS和场同步信号VS,接口对应孔如下所示:
图2 VGA信号接口对应
像素是产生各种颜色的基本单元。根据物理学中的混色原理,三色发光的亮度比例适当,可呈现白色。适当的调整发光比例可以出现不同的颜色。三基色混色原理示意图如下图所示:
图3 三基色混色原理
颜色 | 黑 | 蓝 | 红 | 紫 | 绿 | 青 | 黄 | 白 |
R | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 |
G | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
B | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 |
表1 三基色颜色编码
上表的RBG一共有8组合,也就是说可以产生8种颜色,但是显示器显示的色彩是非常丰富的,远多于8种颜色。那么,这是如何做到的呢?
对于显示器来说,RGB的三个信号其实是模拟信号,其电平的高低,可以表示颜色的深浅,利用这个原理,就可以产生丰富的色彩。为了控制电压的高低,我们必须用到DA芯片。例如,下图中FPGA产生RGB三种信号,这时RGB都是多位的数字信号。DA芯片根据数字信号的值,产生不同电压的模拟信号rgb。
图xx DA芯片工作原理
模块划分和信号列表如下:
模块划分
顶层模块信号列表
信号名 | I/O | 位宽 | 说明 |
clk | I | 1 | 系统工作时钟50MHz。 |
rst_n | I | 1 | 系统复位信号,低电平有效。 |
lcd_hs | O | 1 | 行同步信号。 |
lcd_vs | O | 1 | 场/帧同步信号。 |
lcd_rgb | O | 16 | RBG三基色信号。 |
PLL分频模块信号列表
信号名 | I/O | 位宽 | 说明 |
inclk0 | I | 1 | 输入工作时钟50MHz。 |
c0 | O | 1 | 输出时钟25MHz。 |
VGA接口计数模块信号列表
信号名 | I/O | 位宽 | 说明 |
clk | I | 1 | 系统工作时钟25MHz。 |
rst_n | I | 1 | 系统复位信号,低电平有效。 |
hys | O | 1 | 行同步信号。 |
vys | O | 1 | 场/帧同步信号。 |
lcd_rgb | O | 16 | RBG三基色信号。 |
3 程序设计
顶层模块代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | module vga_exec1( clk , rst_n , lcd_hs , lcd_vs , lcd_rgb );
parameter PICTURE_W = 16;
input clk ; input rst_n ; output lcd_hs ; output lcd_vs ; output [PICTURE_W:0] lcd_rgb ;
wire clk_0 ;
parameter ROW_W = 10;
wire lcd_hs ; wire lcd_vs ; wire [PICTURE_W-1:0] lcd_rgb ;
vga_pll module_1( .inclk0 (clk ), .c0 (clk_0 ) );
vga_driver module_6( .clk (clk_0 ), .rst_n (rst_n ), .hys (lcd_hs ), .vys (lcd_vs ), .lcd_rgb (lcd_rgb) );
endmodule |
VGA计数模块代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | module vga_driver( clk, rst_n, hys, vys, lcd_rgb ); parameter PICTURE_W = 16 ; parameter ROW_W = 10 ;
input clk ; input rst_n ;
output hys ; output vys ;
output [PICTURE_W-1:0] lcd_rgb ; reg [PICTURE_W-1:0] lcd_rgb ;
reg [ROW_W-1:0] h_cnt ; reg [ROW_W-1:0] v_cnt ; reg hys ; reg vys ; reg red_area ; reg green_area ; reg valid_area ;
always @(posedgeclk or negedgerst_n)begin if(!rst_n)begin h_cnt<= 0; end else if(add_h_cnt)begin if(end_h_cnt) h_cnt<= 0; else h_cnt<= h_cnt + 1; end end assign add_h_cnt = 1; assign end_h_cnt = add_h_cnt&&h_cnt== 800 - 1;
always @(posedgeclk or negedgerst_n)begin if(!rst_n)begin v_cnt<= 0; end else if(add_v_cnt)begin if(end_v_cnt) v_cnt<= 0; else v_cnt<= v_cnt + 1; end end assign add_v_cnt = end_h_cnt; assign end_v_cnt = add_v_cnt&&v_cnt== 525 - 1;
always@(posedgeclk or negedgerst_n)begin if(!rst_n)begin hys<= 0; end else if(add_h_cnt&&h_cnt == 96 -1)begin hys<= 1'b1; end else if(end_h_cnt)begin hys<= 1'b0; end end
always @(posedgeclk or negedgerst_n)begin if(!rst_n)begin vys<= 1'b0; end else if(add_v_cnt&&v_cnt == 2 - 1)begin vys<= 1'b1; end else if(end_v_cnt)begin vys<= 1'b0; end end
always @(*)begin red_area = (h_cnt>= (141+ 0) &&h_cnt< (141+ 20)) || (h_cnt>= (141+626) &&h_cnt< (141+646)) || (v_cnt>= ( 32+ 0) &&v_cnt< ( 32+ 20)) || (v_cnt>= ( 32+464) &&v_cnt< ( 32+ 484)); end
always @(*)begin green_area = (h_cnt>= (141+248) &&h_cnt< (141+398)) && (v_cnt>= ( 32+192) &&v_cnt< ( 32+292)); end
always @(*)begin valid_area = h_cnt>=141 &&h_cnt< 787 &&v_cnt>=32 &&v_cnt< 516; end
always @(posedgeclk or negedgerst_n)begin if(rst_n==1'b0)begin lcd_rgb<= 16'h0; end else if(valid_area)begin if(red_area)begin lcd_rgb<= 16'b11111_000000_00000; end else if(green_area)begin lcd_rgb<= 16'b00000_111111_00000; end else begin lcd_rgb<= 16'b11111_111111_11111; end end else begin lcd_rgb<= 0; end end
endmodule |
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。