基于FPGA的VGA接口实现LCD屏AN430彩条显示
一、VGA、AN430简介
1.VGA
VGA(Video Graphics Array) 是 IBM 在 1987 年随 PS/2 机一起推出的一种视频传输 标准,当时具有分辨率高、显示速率快、颜色丰富等优点,在彩色显示器领域得到了广泛的 应用。
VGA 接口就是显卡上输出模拟信号的接口,也叫 D-Sub 接口。VGA 接口是一种 D 型口,上面共有 15 针空,分成三排,每排五个。VGA 接口是目前中低端电脑配置上的主流 口。实物图如下所示:
R、G、B 数据信号,HS、VS 控制信号对应的接口。
显示器采用光栅扫描方式,即轰击荧光屏的电子束在 CRT 屏幕上从左到右(受水平同 步信号 HSYNC 控制)、从上到下(受垂直同步信号 VSYNC 控制)做有规律的移动。电子束 采用光栅扫描方式,从屏幕左上角一点开始,向右逐点进行扫描,形成一条水平线;到达最 右端后,又回到下一条水平线的左端,重复上面的过程;当电子束完成右下角一点的扫描后, 形成一帧。此后,电子束又回到左上方起点,开始下一帧的扫描。这种方法也就是常说的逐 行扫描显示。
扫描频率
完成一行扫描的时间称为水平扫描时间,其倒数称为行频率;完成一帧(整屏)扫 描的时间称为垂直扫描时间,其倒数称为场频率,即刷新一屏的频率,常见的有60Hz,75Hz 等等。标准的 VGA 显示的场频60Hz。
行时序和场时序都需要同步脉冲(Sync a)、显示后沿(Back porch b)、显示时序段 (Display interval c)和显示前沿(Front porch d)四部分。VGA 工业标准显示模式要 求:行同步,场同步都为负极性,即同步脉冲要求是负脉冲。
2.AN430
二、代码
1.param.v
//-----------------------------------------------------------//
// 水平扫描参数的设定480*272 60Hz LCD
//-----------------------------------------------------------//
`define H_SYNC 41 //行同步脉冲(Sync a)
`define H_BP 2 //显示后沿(Back porch b)
`define H_ACTIV 480 //显示时序段(Display interval c)
`define H_FP 2 //显示前沿(Front porch d)
`define H_TOTAL 525 //行周期数 共 525个像素周期
`define H_VLD0 43 //有效显示列 第一列显示数据
`define H_VLD1 523 //有效显示列 最后一列显示数据
//-----------------------------------------------------------//
// 垂直扫描参数的设定480*272 60Hz LCD
//-----------------------------------------------------------//
`define V_SYNC 10 //列同步脉冲(Sync o)
`define V_BP 2 //显示后沿(Back porch p)
`define V_ACTIV 272 //显示时序段(Display interval q)
`define V_FP 2 //显示前沿(Front porch r)
`define V_TOTAL 286 //列周期数 共286行
`define V_VLD0 12 //有效显示区域 第一行
`define V_VLD1 284 //有效显示区域 最后一行
//颜色定义
`define COLOR_R 16'b11111_000000_00000
`define COLOR_G 16'b00000_111111_00000
`define COLOR_B 16'b00000_000000_11111
`define COLOR_P 16'b10110_010111_01001
`define COLOR_PU 47802
`define COLOR_PA 65402
`define COLOR_BL 16'b00000_000000_00000
`define COLOR_W 65535
2.lcd_test
module lcd_test(
input clk ,
input rst_n ,
output [7:0] lcd_r ,
output [7:0] lcd_g ,
output [7:0] lcd_b ,
output lcd_clk ,
output lcd_vsync ,
output lcd_hsync ,
output lcd_de
);
//参数定义
//中间信号定义
pll0 pll0_inst
(
.areset (!rst_n ),
.inclk0 ( clk ),
.c0 ( lcd_clk ),
//.locked (1'b1 )
);
lcd_driver u_lcd_driver
(
/*input */.clk (lcd_clk ),
/*input */.rst_n (rst_n ),
/*output [7:0] */.lcd_r (lcd_r ),
/*output [7:0] */.lcd_g (lcd_g ),
/*output [7:0] */.lcd_b (lcd_b ),
/*output */.lcd_vsync (lcd_vsync ),
/*output */.lcd_hsync (lcd_hsync ),
/*output */.lcd_de (lcd_de )
);
endmodule
3.lcd_driver
`include "param.v"
module lcd_driver
(
input clk ,
input rst_n ,
output [7:0] lcd_r ,
output [7:0] lcd_g ,
output [7:0] lcd_b ,
output lcd_clk ,
output lcd_vsync ,
output lcd_hsync ,
output lcd_de
);
//中间信号定义
reg [9:0] cnt_h ;
wire add_cnt_h ;
wire end_cnt_h ;
reg [9:0] cnt_v ;
wire add_cnt_v ;
wire end_cnt_v ;
wire h_vld ;
wire v_vld ;
reg [15:0] data_rgb ;
//计数器
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt_h <= 0;
end
else if(add_cnt_h)begin
if(end_cnt_h)begin
cnt_h <= 0;
end
else begin
cnt_h <= cnt_h + 1;
end
end
else begin
cnt_h <= cnt_h;
end
end
assign add_cnt_h = 1'b1;
assign end_cnt_h = add_cnt_h && cnt_h == `H_TOTAL-1;
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt_v <= 0;
end
else if(add_cnt_v)begin
if(end_cnt_v)begin
cnt_v <= 0;
end
else begin
cnt_v <= cnt_v + 1;
end
end
else begin
cnt_v <= cnt_v;
end
end
assign add_cnt_v = end_cnt_h;
assign end_cnt_v = add_cnt_v && cnt_v == `V_TOTAL;
assign h_vld = (cnt_h >= `H_VLD0) & (cnt_h <= `H_VLD1);
assign v_vld = (cnt_v >= `V_VLD0) & (cnt_v <= `V_VLD1);
assign lcd_de = h_vld & v_vld;
//data_rgb
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
data_rgb <= 16'b0;
end
else if(cnt_h >= 43 && cnt_h <=103 )begin
data_rgb <= `COLOR_R;
end
else if(cnt_h >= 104 && cnt_h <=164 )begin
data_rgb <= `COLOR_PU;
end
else if(cnt_h >= 165 && cnt_h <=225 )begin
data_rgb <= `COLOR_B;
end
else if(cnt_h >= 226 && cnt_h <=286 )begin
data_rgb <= `COLOR_P;
end
else if(cnt_h >= 287 && cnt_h <=348 )begin
data_rgb <= `COLOR_G;
end
else if(cnt_h >= 349 && cnt_h <=409 )begin
data_rgb <= `COLOR_PA;
end
else if(cnt_h >= 410 && cnt_h <=470 )begin
data_rgb <= `COLOR_BL;
end
else if(cnt_h >= 471 )begin
data_rgb <= `COLOR_W;
end
else begin
data_rgb <= data_rgb;
end
end
assign lcd_r = (h_vld & v_vld) ? {data_rgb[15:11],3'd0}:0;
assign lcd_g = (h_vld & v_vld) ? {data_rgb[10:5],2'd0}:0;
assign lcd_b = (h_vld & v_vld) ? {data_rgb[4:0],3'd0}:0;
assign lcd_vsync = cnt_v >= `V_SYNC;
assign lcd_hsync = cnt_h >= `H_SYNC;
endmodule