PFGA ZYNQ驱动LCD

PFGA/ZYNQ驱动LCD

前言

硬件是zynq 7010开发板,lcd采用RGB888接口,VGA时序。
对于普通的 VGA 显示器,共有 5 个信号:R、G、B 三基色;HS(行同步
信号);VS(场同步信号)。对于时序驱动,VGA 显示器要严格遵循“VGA”工业标准,我们选取分辨率为 480x272@60Hz 模式。通常我们用的显示器都满足工业标准,因此我们设计 VGA 控制器时要参考显示器的技术规格。下图是 VGA 行、场扫描的时序图:
在这里插入图片描述
VGA 扫描,基本元素是行扫描,多行组成一帧,下图显示一行的时序,其中“Active”
Video 是一行视频的有效像素,大部分分辨率时钟中 Top/Left Border 和 Bottom / Right
Border 都是 0。“Blanking”是一行的同步时间,“Blanking”时间加上 Active” Video 时间就
是一行的时间。“Blanking”又分为“Front Porch”、“Sync”、“Back Porch”三段。
在这里插入图片描述

lcd

产生VGA时序

module lcd(
input			clk		,		
input			rst		,		
output			vpg_clk	,		//显示屏时钟
output			vpg_de	,		//显示屏使能
output			vpg_disp,		//显示屏显示模式
output	reg		vpg_hs	,		//行同步信号
output	reg		vpg_vs	,		//场同步信号
output reg [12:0]	cnt_h,		//行计数器
output reg [12:0]	cnt_v		//场计数器
//output	reg[23:0]	RGB			//像素点 rgb值
    );
	
//--------------------------vga时序参数--------------------
//场同步信号
parameter		H_TOTAL = 525 - 1;
parameter		H_SYNC  = 41 - 1;

parameter		H_START = 43 - 1;//数据开始结束计算值
parameter		H_END   = 523 - 1;

//行同步信号
parameter		V_TOTAL = 286 - 1;
parameter		V_SYNC  = 10 - 1;

parameter 		V_START	= 12 - 1;//数据开始结束计算值
parameter		V_END   = 284 - 1;

//场图像数据
parameter		IMG_X   = 150;//方块x
parameter		IMG_Y	= 150;//方块x
parameter		SCREEN_X = 480;//屏幕水平长度
parameter		SCREEN_Y = 272;//屏幕垂直长度

//---------------------------信号-----------------------
/*
reg [11:0]		x;		//方块左上角横坐标
reg 		flag_x;		//方块水平移动方向指示信号
reg [11:0]		y;		//方块左上角纵坐标
reg 		flag_y;		//方块垂直移动方向指示信号
*/
wire 		locked;    	//时钟稳定信号

assign vpg_de = (cnt_h >= H_START) && (cnt_h < H_END) &&
(cnt_v >= V_START) && (cnt_v < V_END);

assign vpg_disp = 1'b1;


  clk_wiz_0 clock
  (
  .clk_out1(vpg_clk),            
  .reset(~rst), 
  .locked(locked),
  .clk_in1(clk)
  );

//-----------------------cnt_h-----------------------
always @(posedge vpg_clk)
begin
	if(!rst)
		cnt_h <= 'd0;
	else if(cnt_h >= H_TOTAL)
		cnt_h <= 'd0;
	else 
		cnt_h <= cnt_h + 1'b1;
end

//-----------------------cnt_v-----------------------
always @(posedge vpg_clk)
begin
	if(!rst)
		cnt_v <= 'd0;
	else if(cnt_v >= V_TOTAL && cnt_h >= H_TOTAL)
		cnt_v <= 'd0;
	else if(cnt_h >= H_TOTAL)
		cnt_v <= cnt_v + 1'b1;
end

//--------------------------vpg_hs-----------------------
always @(posedge vpg_clk)
begin
	if(!rst)
		vpg_hs <= 1'b1;
	else if(cnt_h >= H_TOTAL)
		vpg_hs <= 1'b1;
	else if(cnt_h >= H_SYNC)
		vpg_hs <= 1'b0;
	else 
		vpg_hs <= vpg_hs;
end

//--------------------------vpg_vs-----------------------
always @(posedge vpg_clk)
begin
	if(!rst)
		vpg_vs <= 1'b1;
	else if(cnt_v >= V_TOTAL && cnt_h >= H_TOTAL)
		vpg_vs <= 1'b1;
	else if(cnt_v >= V_SYNC && cnt_h >= H_SYNC)
		vpg_vs <= 1'b0;
	else 
		vpg_vs <= vpg_vs;
end

endmodule

lcd_display

图像显示
例:显示一个移动的方块

module lcd_display(
input				vpg_clk,
input				rst	,
input wire [12:0]	cnt_h,		//行计数器
input wire [12:0]	cnt_v,		//场计数器
output	reg[23:0]	RGB
    );
	
//--------------------------vga时序参数--------------------
//场同步信号
parameter		H_TOTAL = 525 - 1;
parameter		H_SYNC  = 41 - 1;

parameter		H_START = 43 - 1;//数据开始结束计算值
parameter		H_END   = 523 - 1;
//行同步信号
parameter		V_TOTAL = 286 - 1;
parameter		V_SYNC  = 10 - 1;

parameter 		V_START	= 12 - 1;//数据开始结束计算值
parameter		V_END   = 284 - 1;

//场图像数据
parameter		IMG_X   = 150;//方块x
parameter		IMG_Y	= 150;//方块x
parameter		SCREEN_X = 480;//屏幕水平长度
parameter		SCREEN_Y = 272;//屏幕垂直长度
	
reg [11:0]		x;		//方块左上角横坐标
reg 		flag_x;		//方块水平移动方向指示信号
reg [11:0]		y;		//方块左上角纵坐标
reg 		flag_y;		//方块垂直移动方向指示信号
/*
------------------------图像的显示
*/

//--------------------------x-----------------------------
always @(posedge vpg_clk)
begin
	if(!rst)
		x <= 1'b0;
	else if(flag_x == 1'b0 && cnt_v == V_TOTAL && cnt_h == H_TOTAL)
		x <= x + 1'b1;
	else if(flag_x == 1'b1 && cnt_v == V_TOTAL && cnt_h == H_TOTAL)
		x <= x - 1'b1;
end
//移动方块左上角移动方向指示信号
always @(posedge vpg_clk ) begin
	if (!rst) begin
		flag_x <= 1'b0;
	end
	else if (flag_x == 1'b0 && cnt_v ==V_TOTAL && cnt_h == H_TOTAL && x==(H_END - H_START - IMG_X - 1'b1)) begin
		flag_x <= 1'b1;
	end
	else if (flag_x == 1'b1 && cnt_v ==V_TOTAL && cnt_h == H_TOTAL && x=='d1) begin
		flag_x <= 1'b0;
	end
end
//--------------------------y-----------------------------
always @(posedge vpg_clk)
begin
	if(!rst)
		y <= 1'b1;
	else if(flag_y == 1'b0 && cnt_v == V_TOTAL && cnt_h == H_TOTAL)
		y <= y + 1'b1;
	else if(flag_y == 1'b1 && cnt_v == V_TOTAL && cnt_h == H_TOTAL)
		y <= y - 1'b1;
end

//移动方块左上角垂直移动方向指示信号
always @(posedge vpg_clk ) begin
	if (!rst) begin
		flag_y <= 1'b0;
	end
	else if (flag_y == 1'b0 && cnt_v ==V_TOTAL && cnt_h == H_TOTAL && y==(V_END - V_START - IMG_Y - 1'b1)) begin
		flag_y <= 1'b1;
	end
	else if (flag_y == 1'b1 && cnt_v ==V_TOTAL && cnt_h == H_TOTAL && y=='d1 ) begin
		flag_y <= 1'b0;
	end
end
//RGB
always @(posedge vpg_clk ) begin 
	if (!rst) begin
		RGB <='d0;
	end
	else if(cnt_h >= H_START + x && cnt_h <= H_START + IMG_X + x && cnt_v >= V_START + y && cnt_v <= V_START +IMG_Y + y)begin
		RGB <= 24'hFFB6C1;//输出方块
	end
	else if (cnt_h >= H_START && cnt_h < H_END && cnt_v >=V_START && cnt_v < V_END && cnt_h[4:0] >= 'd20) begin
		RGB <=24'h00FF00;//green
	end
	else if (cnt_h >=H_START && cnt_h <H_END && cnt_v >=V_START && cnt_v <V_END && (cnt_h[4:0]>='d10 && cnt_h[2:0]<'d20)) begin
		RGB <=24'h0000FF;//bulue
	end
	else if (cnt_h >=H_START && cnt_h <H_END && cnt_v >=V_START && cnt_v <V_END && cnt_h[4:0]<'d10) begin
		RGB <=24'hFF0000;//red
	end
	else begin
		RGB <= 'd0;
	end
end
endmodule

lcd_top

模块的例化

module lcd_top(
input			clk		,		
input			rst		,		
output			vpg_clk	,		//显示屏时钟
output			vpg_de	,		//显示屏使能
output			vpg_disp,		//显示屏显示模式
output	wire	vpg_hs	,		//行同步信号
output	wire	vpg_vs	,		//场同步信号

output	wire[23:0]	RGB			//像素点 rgb值
    );
wire [12:0]		cnt_h;
wire [12:0]		cnt_v;
	
	lcd inst(
	.clk		(clk)		,		
	.rst		(rst)		,		
	.vpg_clk	(vpg_clk)	,		//显示屏时钟
	.vpg_de		(vpg_de)	,		//显示屏使能
	.vpg_disp	(vpg_disp)	,		//显示屏显示模式
	.vpg_hs		(vpg_hs)	,		//行同步信号
	.vpg_vs		(vpg_vs)	,		//场同步信号
	.cnt_h		(cnt_h)		,		//行计数器
    .cnt_v		(cnt_v)				//场计数器
	);
	
	lcd_display lcd_display_inst(
	.vpg_clk		(vpg_clk)	,
	.rst			(rst)		,
	.cnt_h			(cnt_h)		,
	.cnt_v			(cnt_v)		,
	.RGB			(RGB)
	);
endmodule

纯FPGA小白正在学习FPGA如有错误或者建议希望大佬多多提点。后面会实现显示图片和串口传图等。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值