RGB接口电容触摸屏驱动(三)时序设计

目录

01 时序参数

02 时序实现

设计思路

行扫描时序实现

场扫描时序实现

05 文章总结


大家好,这里是程序员杰克。一名平平无奇的嵌入式软件工程师。

上两篇已经总结和分享了RGB接口TFT-LCD触摸屏的相关内容。本篇使用Verilog语言实现RGB的驱动时序。

前面描述了很多关于时序的内容,但其实在FPGA中实现RGB接口的LCD屏驱动时序还是很简单的。只需要实现行扫描、列扫描的时钟周期控制,并且在有效区域输出对应像素点的RGB数据便可实现控制时序和测试验证难度不大,主要还是要在实际的项目中应用,例如:实时显示摄像头的图像信息等。由于文字篇幅原因,本篇仅对RGB接口驱动时序的实现思想以及Verilog语言代码进行说明


下面正式进入本章推送的内容。

01 时序参数

常用的TFT-LCD屏(帧率为60Hz)时序参数如下图所示,其中,行同步信号时序的单位是时钟脉冲,而场同步信号时序的单位是行周期

对于驱动时序而言,最重要的是确定帧率像素时钟,其他参数由厂商提供。本示例使用的是分辨率为800*480 的4.3寸TFT-LCD屏,使用的帧率为60Hz(每秒60帧图像),时序参数以及相关计算公式如下表所示:

参数数值
H Pulse width128
H Back Porch88
H display area800
H Front Porch40
V Pulse width2
V Back Porch33
V display area480
V Front Porch10
帧率(刷新频率)60
行扫描周期1056
场扫描周期525
像素时钟(MHz)33.3

行扫描周期 = H Pulse width + H Back Porch + H display area + H Front Porch

场扫描周期 = V Pulse width + V Back Porch + V display area + V Front Porch

像素时钟 = 行扫描周期 * 场扫描周期 * 帧率

对于行扫描时序,需要关注的逻辑控制参数如下:

行扫描周期

行同步信号的持续时间 = H Pulse width

行数据的脉冲计数开始值 = H Pulse width + H Back Porch

行数据的脉冲计数结束值 = H Pulse width + H Back Porch + H display area

对于场扫描时序,需要关注的逻辑控制参数如下:

场扫描周期

场同步信号的持续时间 = V Pulse width

场数据的脉冲计数开始值 = V Pulse width + V Back Porch

场数据的脉冲计数结束值 = V Pulse width + V Back Porch + V display area


02 时序实现

对于帧率和分辨率固定的LCD屏幕驱动时序(RGB接口),有以下特点:

    • 图像输出的行扫描、列扫描是周期性的逻辑

    • 同步时序(SYNC)、有效信号(DE)的脉冲固定

  • 设计思路

FPGA设计周期性的时序,可以通过计数器来控制,在计数器的对应count数执行相对应的逻辑;对于逻辑而言,需要考虑的是同步信号、数据有效信号的范围脉冲数、以及扫描周期;行扫描、列扫描对应的设计思路如下(800*480 @60 TFT-LCD屏示例):

时序设计思路描述
行扫描

设计场扫描脉冲计数器,对PCLK脉冲计数;

计数的最大值 = 行扫描周期;

计数自增条件为时钟脉冲高电平(PCLK);

当cnt>H Pulse width时, HSYNC=1,否则为HSYNC=0;

场扫描

设计场扫描脉冲计数器,对行扫描周期计数;

场扫描计数最大值 = 场扫描周期;

计数自增条件为行扫描周期;

当cnt>V Pulse width时, VSYNC=1,否则为VSYNC=0;


  • 行扫描时序实现

由于FPGA设计计数器时,一般从0开始计数,因此行扫描逻辑控制参数需要减去1,如下表所示:

逻辑控制参数说明数值(单位:PCLK)
H_SYNC行同步持续时间128-1
H_DATA_START行数据开始216-1
H_DATA_END行数据结束1016-1
H_PERIOD行扫描周期1055-1

Verilog实现代码如下:

parameter  H_SYNC        = 11'd127    ;parameter  H_DATA_START  = 11'd215    ;parameter  H_DATA_END    = 11'd1015   ;parameter  H_PERIOD      = 11'd1055   ;//行扫描控制时序reg  [10:0]  h_cnt;always @(posedge pclk) begin  if(rst_n == 1'b0) begin    h_cnt  <= 11'd0;  end  else if(h_cnt == H_PERIOD) begin    h_cnt  <= 11'd0;  end  else begin    h_cnt  <= h_cnt + 1'b1;  endendassign hsync  = (h_cnt > H_SYNC) ? 1'b1 : 1'b0;assign h_index = (h_cnt > H_DATA_START) ? (h_cnt - H_DATA_START) : 11'd0;

  • 场扫描时序实现

由于FPGA设计计数器时,一般从0开始计数,因此行扫描逻辑控制参数需要减去1,如下表所示:

参数说明数值(单位:PCLK)
V_SYNC行同步持续时间2-1
V_DATA_START行数据开始216-1
V_DATA_END行数据结束1016-1
V_PERIOD行扫描周期1055-1

Verilog实现代码如下:​​​​​​

parameter  v_SYNC        = 11'd1    ;parameter  v_DATA_START  = 11'd34   ;parameter  v_DATA_END    = 11'd514  ;parameter  v_PERIOD      = 11'd524  ;//场扫描控制时序reg  [10:0]  v_cnt;always @(posedge pclk) begin  if(rst_n == 1'b0) begin    v_cnt  <= 11'd0;  end  else if(v_cnt == v_PERIOD) begin    v_cnt  <= 11'd0;  end  else if(h_cnt == H_PERIOD) begin    v_cnt  <= v_cnt + 1'b1;  end  else begin    v_cnt  <= v_cnt;  endendassign vsync  = (v_cnt > v_SYNC) ? 1'b1 : 1'b0;assign v_index  = (v_cnt > v_DATA_START) ? (v_cnt - v_DATA_START) : 11'd0;

完整Verilog代码如下:

module parallel_rgb_control
#
(
  parameter  H_SYNC        = 11'd127   ,
  parameter  H_DATA_START  = 11'd215   ,
  parameter  H_DATA_END    = 11'd1015  ,
  parameter  H_PERIOD      = 11'd1055  ,

  parameter  v_SYNC        = 11'd1    ,
  parameter  v_DATA_START  = 11'd34   ,
  parameter  v_DATA_END    = 11'd514  ,
  parameter  v_PERIOD      = 11'd524  
)
(
  input    wire        pclk    ,
  input    wire        rst_n    ,
  
  output  wire          hsync    ,
  output  wire  [10:0]  h_index  ,
  
  output  wire          vsync    ,
  output  wire  [10:0]  v_index  ,
  
  output  wire        de      
);
//==========================================================//
//行扫描控制时序
reg	[10:0]	h_cnt;
always @(posedge pclk) begin
	if(rst_n == 1'b0) 
		h_cnt <= 11'd0;
	else if(h_cnt == H_PERIOD) 
		h_cnt <= 11'd0;
	else 
		h_cnt <= h_cnt + 1'b1;
end

//hsync control timing logic
always @(posedge pclk) begin
	if(rst_n == 1'b0) 
		hsync <= 1'b0;
	else if(h_cnt > H_SYNC) 
		hsync <= 1'b1;
	else
		hsync <= 1'b0;
end

assign h_index = (de) ? (h_cnt - H_DATA_START) : 11'd0;
//==========================================================//
//场扫描控制时序
reg	[10:0]	v_cnt;
always @(posedge pclk) begin
	if(rst_n == 1'b0) begin
		v_cnt <= 11'd0;
    end
	else if(h_cnt == H_PERIOD) begin
		if(v_cnt == V_PERIOD) 
			v_cnt <= 11'd0;
		else 
			v_cnt <= v_cnt + 1'b1;
	end
	else begin
		v_cnt <= v_cnt;
    end
end

//vsync control timing logic
always @(posedge pclk) begin
	if(rst_n == 1'b0) 
		vsync <= 1'b0;
	else if(v_cnt > V_SYNC) 
		vsync <= 1'b1;
	else 
		vsync <= 1'b0;
end

assign v_index = (de) ? (v_cnt - V_DATA_START) : 11'd0;

//============================================================//
//de signal timing control logic
wire h_valid = (h_cnt >= H_DATA_START) && (h_cnt < H_DATA_END);
wire v_valid = (v_cnt >= V_DATA_START) && (v_cnt < V_DATA_END);
always @(posedge pclk) begin
	if(rst_n == 1'b0)
		de <= 1'b0;
	else if(h_valid && v_valid)
		de <= 1'b1;
	else 
		de <= 1'b0;
end

endmodule


05 文章总结

对于RGB接口的TFT-LCD屏的时序驱动代码还是较为简单的。使用文字描述实际的应用并且让人容易理解,还是很困难的。基于此,本篇仅仅只是分享了RGB接口周期时序的实现,对于具体的数据输出显示的应用并未说明。倘若有兄弟想了解实际应用,可以添加杰克的微信号来交流。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

杰克拉力船长

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

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

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

打赏作者

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

抵扣说明:

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

余额充值