FPGA-LCD基础驱动

      LCD的接口时序波形如图所示。VSYNC是场同步信号,低电平有效,从时序图可以看出,VSYNC是每一场(即也可以理解为每送一幅完整图像)的同步信号;与此类似,HSYNC是行同步信号,也是在每一行数据传输的开始产生几个时钟周期的低脉冲。这两个信号用于同步当前的数据信号,根据固定的脉冲约定,我们在某些时钟上升沿前将图像数据送到数据总线上供LCD内部锁存。

2.jpg

LCD驱动时序波形

这是LCD时序图中对应的时间参数。

表8.11 LCD驱动时序参数表

信号

列项

标记

最小值

标准值

最大值

单位

Dclk

频率

Tosc

 

156

 

ns

最大时间

Tch

 

78

 

ns

 

最小时间

Tcl

 

78

 

ns

 

Data

建立时间

Tsu

12

  

ns

保持时间

Thd

12

  

ns

 

Hsync

周期

TH

 

408

 

Tosc

脉冲宽度

THS

5

30

 

Tosc

 

后沿

THB

 

38

 

Tosc

 

显示周期

TEP

 

320

 

Tosc

 

同步周期

THE

36

68

88

Tosc

 

前沿

THF

 

20

 

Tosc

 

Vsync

周期

TV

 

262

 

TH

脉冲宽度

TVS

1

3

5

TH

 

后沿

TVB

 

15

 

TH

 

显示周期

TVD

 

240

 

TH

 

前沿

TVF

2

4

 

TH

 

 

相同的方式驱动的程序写法类似:

顶层文件:

module top(ext_clk_25m,ext_rst_n,lcd_light_en,lcd_clk,lcd_hsy,lcd_vsy,lcd_r,lcd_g,lcd_b
    );
	input ext_clk_25m;
	input ext_rst_n;
	output lcd_light_en;
	output lcd_clk;
	output lcd_hsy;
	output lcd_vsy;
	output [4:0] lcd_r;
	output [5:0] lcd_g;
	output [4:0] lcd_b;

	lcd_controller uut_lcd_controller(
	.clk(ext_clk_25m),
	.rst_n(ext_rst_n),
	.lcd_light_en(lcd_light_en),
	.lcd_clk(lcd_clk),
	.lcd_hsy(lcd_hsy),
	.lcd_vsy(lcd_vsy),
	.lcd_r(lcd_r),
	.lcd_g(lcd_g),
	.lcd_b(lcd_b)
    );
endmodule

lcd_controller.v

module lcd_controller(clk,rst_n,lcd_light_en,lcd_clk,lcd_hsy,lcd_vsy,lcd_r,lcd_g,lcd_b
    );
	input clk;
	input rst_n;
	output lcd_light_en;
	output lcd_clk;
	output reg lcd_hsy;
	output reg lcd_vsy;
	output [4:0] lcd_r;
	output [5:0] lcd_g;
	output [4:0] lcd_b;
	
	parameter HSY_TH=9'D408-1'D1;//周期
	parameter HSY_THS=9'D30     ;//脉冲宽度
	parameter HSY_THB=9'D38     ;//后沿
	parameter HSY_TEP=9'D320    ;//显示周期
	parameter HSY_THE=9'D68     ;//同步周期
	parameter HSY_THF=9'D20     ;//前沿
	parameter VSY_TV=9'D262-1'D1;//周期
	parameter VSY_TVS=9'D3      ;//脉冲宽度
	parameter VSY_TVB=9'D15     ;//后沿
	parameter VSY_TVD=9'D240    ;//显示周期
	parameter VSY_TVF=9'D4      ;//前沿
	//lcd背光常开
	assign lcd_light_en=1'b1;
	
	//配置驱动时钟6.25mHz
	reg [1:0] lcd_cnt;
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			lcd_cnt<=1'b0;
		end
		else begin
			lcd_cnt<=lcd_cnt+1'b1;
		end
	end
	assign lcd_clk=lcd_cnt[1];
	wire dchange ={lcd_cnt==2'd2};
	//X和Y轴计数器
	reg[8:0] xcnt;
	reg[8:0] ycnt;
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			xcnt<=1'b0;
		end
		else if(dchange==1'b1)begin
			if(xcnt==HSY_TH)begin
				xcnt<=1'b0;
			end
			else begin
				xcnt<=xcnt+1'b1;
			end
		end
		else;
	end
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			ycnt<=1'b0;
		end
		else if(dchange&&xcnt==HSY_TH)begin
			if(ycnt==VSY_TV)begin
				ycnt<=1'b0;
			end
			else begin
				ycnt<=ycnt+1'b1;
			end
		end
		else begin
			ycnt<=ycnt;
		end
	end
	
	//lcd显示的有效区域
	reg valid;
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			valid<=1'b0;
		end
		else if(ycnt>=(VSY_TVS+VSY_TVB)&&ycnt<(VSY_TVS+VSY_TVB+VSY_TVD)&&
		xcnt>=(HSY_THS+HSY_THB)&&xcnt<(HSY_TEP+HSY_THB+HSY_THE))begin
			valid<=1'b1;
		end
		else begin
			valid<=1'b0;
		end
	end
	
	//LCD驱动行场同步信号产生逻辑
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			lcd_hsy<=1'b1;
		end
		else if(xcnt==1'b0)begin
			lcd_hsy<=1'b0;
		end
		else if(xcnt>=HSY_THS)begin
			lcd_hsy<=1'b1;
		end
		else begin
			lcd_hsy<=lcd_hsy;
		end
	end
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			lcd_vsy<=1'b1;
		end
		else if(ycnt==1'b0)begin
			lcd_vsy<=1'b0;
		end
		else if(ycnt>=VSY_TVS)begin
			lcd_vsy<=1'b1;
		end
		else begin
			lcd_vsy<=lcd_vsy;
		end
	end
	
	//产生显示条纹
	reg [3:0]tmp_cnt;
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			tmp_cnt<=1'b0;
		end
		else if(valid==1'b0)begin
			tmp_cnt<=1'b0;
		end
		else if(valid&&dchange)begin
			if(tmp_cnt<4'd9)begin
				tmp_cnt<=tmp_cnt+1'b1;
			end
			else begin
				tmp_cnt<=1'b0;
			end
		end
	end
	reg [15:0]lcd_db_rgb;
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			lcd_db_rgb<=16'd0;
		end
		else if(valid)begin
			if((tmp_cnt==4'd9)&&dchange)begin
				lcd_db_rgb[15:11]<=lcd_db_rgb[15:11]+1'b1;
			end
			else;
		end
		else begin
			lcd_db_rgb<=1'b0;
		end
	end
	assign lcd_r =valid ? lcd_db_rgb[15:11]:5'd0;
	assign lcd_g =valid ? lcd_db_rgb[10:5]:6'd0;
	assign lcd_b =valid ? lcd_db_rgb[4:0]:5'd0;
	
endmodule

下板子效果图: 

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Vuko-wxh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值