银杏科技有限公司旗下技术文档发布平台 | |||
技术支持电话 | 0379-69926675-801 | ||
技术支持邮件 | Gingko@vip.163.com | ||
版本 | 日期 | 作者 | 修改内容 |
---|---|---|---|
V1.0 | 2019-12-25 | gingko | 初次建立 |
注意事项1: 核心板在上,转接板在下,注意FPC转接板下边缘和核心板下边缘要对齐,确保引脚连接正确(如图30-1中①所示)。
注意事项2: FPC软线与FPC接口连接时,请确认软排线接口处蓝色绝缘皮朝上(如图30-1中②③所示)。
注意事项3: 下载程序前请确认FPC连接线无误,且iCore3核心板引脚与PIN.tcl文件中绑定引脚相互对应。
此次实验采用的是分辨率800 * 480的7寸液晶屏。从图30-1中可以看到,右边即是此次实验所用的TFT_LCD液晶屏模块。绿色电路板为TFT_LCD显示屏的硬件驱动电路(显示屏在电路板的背面),包括背光LED驱动电路、液晶驱动电压电路和AD转换电路。本次实验我们是为了实现FPGA控制TFT_LCD屏的显示,因此,主要讲解如何通过Verilog编程实现TFT_LCD的显示驱动。 液晶屏的现实控制包括背光LED点亮和色彩显示的控制。TFT_LCD液晶屏的背光LED亮度是可以通过PWM信号来调节的,调整PWM信号的占空比,可以控制屏幕亮度的高低。亦可直接将PWM信号赋值1或0,实现屏幕点亮熄灭之间的转换。背光LED只能调节屏幕的亮度,而色彩则需要通过对像素点RGB值的刷新实现。
TFT_LCD作为液晶屏显示技术的一种,和VGA接口的显示器控制很类似,都是通过行列扫描实现色彩的显示。下图是关于FPC接口引脚的介绍以及引脚信号定义: 从上图可以看出,PWM信号点亮背光LED,RGB信号是565格式的16位颜色数据,还有行场同步信号,数据使能信号以及驱动时钟信号。24 ~27号引脚是触摸屏驱动电路AD转换部分的控制引脚,这次试验目的是实现液晶屏彩条显示,因此先不理会触摸相关的信号。 从上图可以看出,TFT_LCD液晶推荐的驱动时钟频率为33.3MHz,我们用的是30MHz。以DCLK单个时钟周期为单位,行扫描需要1056个时钟周期,列扫描则需要525个。可以发现,本次实验采用的7寸TFT_LCD屏幕驱动和VGA驱动的时序控制方式几乎一样,那么VGA驱动部分的代码我们就可以拿来复用了。同样的,TFT_LCD屏在顺序扫描时,通过控制行列像素RGB值的不同,可以实现红绿蓝三色条纹的显示。
本实验例程包括四个功能模块,如图30-3所示,其中TFT_Ctrl实现TFT液晶屏的显示驱动;而TFT_Display模块实现LCD屏幕显示内容的控制。 在Tools→netlist viewers→RTL Viewer 中查看系统RTL视图,可以明确看到上述模块,如下图所示: RST_Ctrl模块为系统提供初始复位信号。PLL模块是ATLPLL IP核的例化,为触摸屏和系统提供30MHz时钟信号。这里主要讲一下TFT_Ctrl模块和TFT_Display模块。 打开实验所带例程,双击TFT_Ctrl.v文件,可以看到如下部分代码:
//--------------------Sync_H---------------------------------// reg[10:0] cnt_h = 11'd0; //行同步信号计数器 reg Sync_H_r = 1'd1;//行同步信号 always @(posedge TFT_CLK or negedge RST_n) if (!RST_n) cnt_h <= 11'd0; else if (cnt_h == 1055) //每行填充1056个列像素 cnt_h <= 11'd0; else cnt_h <= cnt_h + 1'd1; always @(posedge TFT_CLK or negedge RST_n) if (!RST_n) Sync_H_r <= 1'd1; else begin if (cnt_h == 0) Sync_H_r <= 1'd0; //行同步信号拉低 else if (cnt_h == 1) Sync_H_r <= 1'd1; //行同步信号拉高 end assign Sync_H = Sync_H_r; //输出行同步信号
对系统时钟周期进行计数,计满1056个系统时钟周期为一个行扫描周期,并且在每次行扫描的第三个时钟周期拉高一次作为行同步信号。
同理,场扫描是以行扫描为基础进行计数,计满526行作为一帧,并给出一个场同步信号,这里提一点,行同步信号和列同步信号均为一个系统时钟周期。
行列显示信号和LED背光信号是相互独立控制的,本例程中我们是对系统时钟进行分频,产生一个PWM_CLK的时钟信号,再以此时钟产生一个PWM信号,用以驱动背光LED。这个PWM信号简单处理的话可以直接赋值为1,相当于输出一个占空比100%的PWM信号。
//------------------------PWM_Control------------------------------// /*控制占空比,调节背光的亮度*/ reg [15:0]cnt_n,t; reg pwm; always @(posedge TFT_CLK or negedge RST_n) if (!RST_n) t <= 16'd127; else t <= pwm_temp; always @(posedge PWM_CLK or negedge RST_n) if (!RST_n) cnt_n <= 16'd0; else if (cnt_n == 16'd255) cnt_n <= 16'd0; else cnt_n <= cnt_n + 1'd1; always @(posedge PWM_CLK or negedge RST_n) if (!RST_n) pwm <= 1'd0; else if(cnt_n <= t) pwm <= 1'd0; else pwm <= 1'd1; assign PWM =(t == 16'd0) ? 1'd1 : pwm; //输出PWM信号
上面这段代码我们引入了一个变量t,用于接收TFT_Displya模块传输过来控制占空比的常量,同时通过将t的值和cnt_n的值进行比较,控制PWM信号的占空比。
再看例程中的TFT_Display.v文件,这部分代码比较简单,给pwm_temp变量赋值,并传递到TFT_Ctrl模块。这里设置pwm_temp变量的目的是为了方便在此基础上做亮度调节控制,可以不用修改TFT_Crtl模块的代码就实现对亮度的控制。如果想简单处理,可以直接对PWM赋值,如:
assign PWM =1'd0;//这里PWM信号为低电平点亮LED
则是相当于100%占空比点亮背光LED
TFT_Display.v 文件下的另一块代码即是实现三色显示控制的。
//--------------------IMG_RGB------------------------------// reg [15:0]IMG_RGB_r; always@(posedge TFT_CLK or negedge RST_n) if (!RST_n) IMG_RGB_r<=16'b0; else if(DE) begin if(CNT_V<=11'd183) IMG_RGB_r<=16'b11111_000000_00000;//上 条纹显示红色 else if(CNT_V>=11'd342) IMG_RGB_r<=16'b00000_000000_11111;//下 条纹显示蓝色 else IMG_RGB_r<=16'b00000_111111_00000;//中 条纹显示绿色 end assign IMG_RGB = IMG_RGB_r;
从这部分代码可以看到,和VGA驱动一样,均是对行扫描计数进行判断,在某些行范围内,对RGB色彩控制变量分别赋予不同的值,以此实现TFT_LCD屏的条纹显示控制。
在顶层文件TFT_Display_Top.v文件中大家可能留意到右这么几行代码:
//50P液晶接口引脚设置 assign MODE = 1'd0; //模式选择,这里我们选用的SYNC模式,MODE=0; assign DITHB = 1'd1; //控制内部抖动的的使能信号,一般拉高,失能 assign UD = 1'd0; //扫描方式控制,0表示从上到下的扫描方式 assign LR = 1'd1; //扫描方式控制,1表示从左到右的方式扫描
那么这几行代码代表什么含义呢,还是需要我们从手册里找。这几个信号是配置我们的TFT_LCD液晶屏的模式的。MODE字是模式控制,在TFT_LCD的显示控制中有HV模式和DE模式,这里我们选用的是HV模式,即TFT_LCD屏的RGB数据同步是靠行列同步信号控制的,也就是SYNC模式。 而DE模式是指显示的时候RGB数据的同步是靠DE信号控制的,DE模式行同步信号线和列同步信号线都要拉低。DITHB内部消抖控制信号,这里我们默认置高。 UD和LR是扫描方式选择,此处我们选择的是从屏幕的左上角开始,按照从左到右从上到下的方式扫描。这里扫描方式的选择和显示画面的控制是关联的,因为某一时钟像素点的相对位置和RGB数据需要相互对应。 以上这几个信号通过直接赋值的方式控制了液晶屏的显示方式等设定。