您当前的位置: 首页 >  fpga开发

正点原子

暂无认证

  • 1浏览

    0关注

    382博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

【正点原子FPGA连载】 第十八章 RGB LCD彩条显示实验 -摘自【正点原子】领航者ZYNQ之FPGA开发指南_V2.0

正点原子 发布时间:2022-01-04 18:07:07 ,浏览量:1

1)实验平台:正点原子领航者ZYNQ开发板 2)平台购买地址:https://item.taobao.com/item.htm?&id=606160108761 3)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-301505-1-1.html 4)对正点原子FPGA感兴趣的同学可以加群讨论:994244016 5)关注正点原子公众号,获取最新资料更新 在这里插入图片描述

第十八章 RGB LCD彩条显示实验

TFT-LCD是一种液晶显示屏,它采用薄膜晶体管(TFT)技术提升图像质量,如提高图像亮度和对比度等。相比于传统的CRT显示器,TFT-LCD有着轻薄、功耗低、无辐射、图像质量好等诸多优点,因此广泛应用于电视机、电脑显示器、手机等各种显示设备中。 本章包括以下几个部分: 18.1 RGB LCD简介 18.2 实验任务 18.3 硬件设计 18.4 程序设计 18.5 下载验证   18.1 RGB LCD简介 TFT-LCD的全称是Thin Film Transistor-Liquid Crystal Display,即薄膜晶体管液晶显示屏,它显示的每个像素点都是由集成在液晶后面的薄膜晶体管独立驱动,因此TFT-LCD具有较高的响应速度以及较好的图像质量。正点原子推出的RGB LCD液晶屏较多,7寸RGB LCD屏的实物图如下图所示: 第十八章 RGB LCD彩条显示实验 TFT-LCD是一种液晶显示屏,它采用薄膜晶体管(TFT)技术提升图像质量,如提高图像亮度和对比度等。相比于传统的CRT显示器,TFT-LCD有着轻薄、功耗低、无辐射、图像质量好等诸多优点,因此广泛应用于电视机、电脑显示器、手机等各种显示设备中。 本章包括以下几个部分: 18.1 RGB LCD简介 18.2 实验任务 18.3 硬件设计 18.4 程序设计 18.5 下载验证   18.1 RGB LCD简介 TFT-LCD的全称是Thin Film Transistor-Liquid Crystal Display,即薄膜晶体管液晶显示屏,它显示的每个像素点都是由集成在液晶后面的薄膜晶体管独立驱动,因此TFT-LCD具有较高的响应速度以及较好的图像质量。正点原子推出的RGB LCD液晶屏较多,7寸RGB LCD屏的实物图如下图所示: 在这里插入图片描述

图 7.5.13.1 ATK-7’RGB接口TFT液晶屏模块 液晶显示器是现在最常用到的显示器,手机、电脑、各种人机交互设备等基本都用到了LCD,最常见的就是手机和电脑显示器了。由于笔者不是LCD从业人员,对于LCD的具体原理不了解,百度百科对于 LCD的原理解释如下: LCD的构造是在两片平行的玻璃基板当中放置液晶盒,下基板玻璃上设置 TFT(薄膜晶体管),上基板玻璃上设置彩色滤光片,通过TFT上的信号与电压改变来控制液晶分子的转动方向,从而达到控制每个像素点偏振光出射与否而达到显示目的。我们现在要在领航者开发板上使用LCD,所以不需要去研究LCD 的具体实现原理,我们只需要从使用的角度去关注 LCD 的几个重要点: 1、分辨率 提起LCD显示器,我们都会听到720P、1080P、2K或4K这样的字眼,这个就是LCD显示器分辨率。 LCD显示器都是由一个一个的像素点组成,像素点就类似一个灯(在OLED显示器中,像素点就是一个小灯),这个小灯是RGB灯,也就是由R(红色)、G(绿色)和B(蓝色)这三种颜色组成的,而RGB就是光的三原色。 1080P的意思就是一个LCD屏幕上的像素数量是1920*1080个,也就是这个屏幕一列1080个像素点,一共 1920列,如图 7.5.13.2所示: 在这里插入图片描述

图 7.5.13.2 像素点排布 图 7.5.13.2就是1080P显示器的像素示意图,X轴就是LCD显示器的横轴,Y轴就是显示器的竖轴。图中的小方块就是像素点,一共有19201080=2073600个像素点。左上角的A点是第一个像素点,右下角的C点就是最后一个像素点。2K就是25601440个像素点,4K是38402160个像素点。很明显,在LCD尺寸不变的情况下,分辨率越高越清晰。同样的,分辨率不变的情况下,LCD尺寸越小越清晰。比如我们常用的24寸显示器基本都是1080P的,而我们现在使用的5寸的手机基本也是1080P的,但是手机显示细腻程度就要比24寸的显示器要好很多!由此可见,LCD显示器的分辨率是一个很重要的参数,但是并不是分辨率越高的LCD就越好。衡量一款LCD的好坏,分辨率只是其中的一个参数,还有色彩还原程度、色彩偏离、亮度、可视角度、屏幕刷新率等其他参数。 2、像素格式 上面讲了,一个像素点就相当于一个RGB小灯,通过控制R、G、B这三种颜色的亮度就可以显示出各种各样的色彩。那该如何控制R、G、B这三种颜色的显示亮度呢?一般一个R、G、B这三部分分别使用8bit的数据,那么一个像素点就是8bit3=24bit,也就是说一个像素点3个字节,这种像素格式称为 RGB888。当然常用的像素点格式还有RGB565,只需要两个字节,但在色彩鲜艳度上较差一些。我们领航者开发板上的RGB TFT-LCD接口采用的RGB888的像素格式,共需要24位,每一位对应RGB的颜色分量如下图所示: 在这里插入图片描述

图 7.5.13.3 RGB888数据格式 在图 7.5.13.3中,一个像素点占用3个字节,其中bit23bit16是RED通道,bit15bit8是GREEN通道,bit7~bit0是BLUE通道。所以红色对应的值就是24’hFF0000,绿色对应的值就是24’h00FF00,蓝色对应的值为24’h0000FF。通过调节R、G、B的比例可以产生其它的颜色,比如24’hFFFF00就是黄色,24’h000000就是黑色,24’hFFFFFF就是白色。大家可以打开电脑的“画图”工具,在里面使用调色板即可获取到想要的颜色对应的数值,如图 7.5.13.4所示: 在这里插入图片描述

图 7.5.13.4 调色板颜色选取 3、LCD屏幕接口 LCD屏幕或者说显示器有很多种接口,比如在显示器上常见的VGA、HDMI、DP等等,领航者开发板支持RGB接口的LCD和HDMI接口的显示器。本章我们介绍的是RGB LCD接口,RGB LCD接口的信号线如下表所示: 表 18.1.1 RGB数据线 信号线 描述 R[7:0] 8根红色数据线 G[7:0] 8根绿色数据线 B[7:0] 8根蓝色数据线 DE 数据使能线 VSYNC 垂直同步信号线 HSYNC 水平同步信号线 PCLK 像素时钟信号线 表 18.1.1就是RGB LCD的信号线,R[7:0]、G[7:0]和B[7:0]是24位数据,DE、VSYNC、HSYNC和PCLK是四个控制信号。 正点原子一共有五款RGB LCD屏幕,型号分别为ATK-4342(4.3寸,480272)、ATK-4384(4.3寸,800480)、ATK-7084(7寸,800480)、ATK-7016(7寸,1024600)和ATK-1018(10.1寸,1280*800)。这里以ATK-7016这款屏幕为例讲解,ATK-7016的屏幕接口原理图如所示: 在这里插入图片描述

图 7.5.13.5 RGB LCD液晶屏幕接口 图中J1就是对外接口,是一个40PIN的FPC座(0.5mm间距),通过FPC线,可以连接到领航者ZYNQ开发板上面,从而实现和开发板的连接。该接口十分完善,采用RGB888格式,并支持触摸屏和背光控制。右侧的几个电阻,并不是都焊接的,而是可以用户自己选择。默认情况,R1和R6 焊接,设置LCD_LR和LCD_UD,控制LCD的扫描方向,是从左到右,从上到下(横屏看)。而LCD_R7/G7/B7 则用来设置LCD的ID,由于RGBLCD没有读写寄存器,也就没有所谓的ID,这里我们通过在模块上面,控制R7/G7/B7的上/下拉,来自定义LCD模块的ID,帮助MCU判断当前LCD面板的分辨率和相关参数,以提高程序兼容性。这几个位的设置关系如表 18.1.2所示: 表 18.1.2 RGB LCD模块和ID对应关系 M2 LCD_B7 M1 LCD_G7 M0 LCD_R7 LCD ID 说明 0 0 0 4342 ATK-4342 RGB LCD模块,分辨率:480272 0 0 1 7084 ATK-7084 RGB LCD模块,分辨率:800480 0 1 0 7016 ATK-7016 RGB LCD模块,分辨率:1024600 1 0 0 4384 ATK-4384 RGB LCD模块,分辨率:800480 1 0 1 1018 ATK-1018 RGB LCD模块,分辨率:1280800 X X X NC 暂时未用到 ATK-7016模块,就设置M2:M0 = 010即可。这样,我们在程序里面,读取LCD_R7/G7/B7,得到M0:M2 的值,从而判断RGB LCD模块的型号,并执行不同的配置,即可实现不同LCD模块的兼容。 4、LCD时间参数 如果将LCD显示一帧图像的过程想象成绘画,那么在显示的过程中就是用一根“笔”在不同的像素点画上不同的颜色。这根笔按照从左至右、从上到下的顺序扫描每个像素点,并且在像素画上对应的颜色,当画到最后一个像素点的时候一幅图像就绘制好了。假如一个LCD的分辨率为1024600,那么其扫描如图 7.5.13.6所示: 在这里插入图片描述

图 7.5.13.6 LCD一帧图像扫描图 结合图 7.5.13.6我们来看一下LCD是怎么扫描显示一帧图像的。一帧图像也是由一行一行组成的。HSYNC是水平同步信号,也叫做行同步信号,当产生此信号的话就表示开始显示新的一行了,所以此信号都是在图 7.5.13.6的最左边。VSYNC信号是垂直同步信号,也叫做帧同步信号,当产生此信号的话就表示开始显示新的一帧图像了,所以此信号在图 7.5.13.6的左上角。 在图 7.5.13.6可以看到有一圈“黑边”,真正有效的显示区域是中间的白色部分。那这一圈“黑边”是什么东西呢?这就要从显示器的“祖先”CRT显示器开始说起了,CRT显示器就是以前很常见的那种大屁股显示器,在2019年应该很少见了,如果在农村应该还是可以见到的。CRT显示器屁股后面是个电子枪,这个电子枪就是我们上面说的“画笔”,电子枪打出的电子撞击到屏幕上的荧光物质使其发光。只要控制电子枪从左到右扫完一行(也就是扫描一行),然后从上到下扫描完所有行,这样一帧图像就显示出来了。也就是说,显示一帧图像电子枪是按照‘Z’形在运动,当扫描速度很快的时候看起来就是一幅完成的画面了。 当显示完一行以后会发出HSYNC信号,此时电子枪就会关闭,然后迅速的移动到屏幕的左边,当 HSYNC信号结束以后就可以显示新的一行数据了,电子枪就会重新打开。在HSYNC信号结束到电子枪重新打开之间会插入一段延时,这段延时就是图 7.5.13.6中的HBP。当显示完一行以后就会关闭电子枪等待 HSYNC信号产生,关闭电子枪到HSYNC信号产生之间会插入一段延时,这段延时就是图 7.5.13.6中的HFP 信号。同理,当显示完一帧图像以后电子枪也会关闭,然后等到VSYNC信号产生,期间也会加入一段延时,这段延时就是图 7.5.13.6中的VFP。VSYNC信号产生,电子枪移动到左上角,当VSYNC信号结束以后电子枪重新打开,中间也会加入一段延时,这段延时就是图 7.5.13.6中的VBP。 HBP、HFP、VBP和VFP就是导致图 7.5.13.6中黑边的原因,但是这是CRT显示器存在黑边的原因,现在是LCD显示器,不需要电子枪了,那么为何还会有黑边呢?这是因为RGB LCD屏幕内部是有一个IC 的,发送一行或者一帧数据给IC,IC是需要反应时间的。通过这段反应时间可以让IC识别到一行数据扫描完了,要换行了,或者一帧图像扫描完了,要开始下一帧图像显示了。因此,在LCD屏幕中继续存在HBP、HFP、VPB和VFP这四个参数的主要目的是为了锁定有效的像素数据。 5、RGB LCD屏幕时序 上面介绍了LCD的时间参数,我们接下来看一下行显示对应的时序图,如图 7.5.13.7所示。 在这里插入图片描述

图 7.5.13.7 LCD行显示时序 图 7.5.13.7就是RGB LCD的行显示时序,我们来分析一下其中重要的几个参数: HSYNC:行同步信号,当此信号有效的时候就表示开始显示新的一行数据,查阅所使用的LCD数据手册可以知道此信号是低电平有效还是高电平有效,图 7.5.13.7为低电平有效。 HSPW:行同步信号宽度,也就是HSYNC信号持续时间。HSYNC信号不是一个脉冲,而是需要持续一段时间才是有效的,单位为CLK。 HBP:行显示后沿(或后肩),单位是CLK。 HOZVAL:行有效显示区域,即显示一行数据所需的时间,假如屏幕分辨率为1024*600,那么HOZVAL 就是1024,单位为CLK。 HFP:行显示前沿(或前肩),单位是CLK。 当HSYNC信号发出以后,需要等待HSPW+HBP个CLK时间才会接收到真正有效的像素数据。当显示完一行数据以后需要等待HFP个CLK时间才能发出下一个HSYNC信号,所以显示一行所需要的时间就是:HSPW + HBP + HOZVAL + HFP。 一帧图像就是由很多个行组成的,RGB LCD的帧显示时序如图 7.5.13.8所示:在这里插入图片描述

图 7.5.13.8 LCD帧显示时序 图 7.5.13.8就是RGB LCD的帧显示时序,我们来分析一下其中重要的几个参数: VSYNC:帧(场)同步信号,当此信号有效的时候就表示开始显示新的一帧数据,查阅所使用的LCD数据手册可以知道此信号是低电平有效还是高电平有效,图 7.5.13.8为低电平有效。 VSPW:帧同步信号宽度,也就是VSYNC信号持续时间,单位为1行的时间。 VBP:帧显示后沿(或后肩),单位为1行的时间。 LINE:帧有效显示区域,即显示一帧数据所需的时间,假如屏幕分辨率为1024600,那么LINE就是600行的时间。 VFP:帧显示前沿(或前肩),单位为1行的时间。 显示一帧所需要的时间就是:VSPW+VBP+LINE+VFP个行时间,最终的计算公式: T = (VSPW+VBP+LINE+VFP) * (HSPW + HBP + HOZVAL + HFP) 因此我们在配置一款RGB LCD屏的时候需要知道这几个参数:HSPW(行同步)、HBP(行显示后沿)、HOZVAL(行有效显示区域)、HFP(行显示前沿)、VSPW(场同步)、VBP(场显示后沿)、LINE(场有效显示区域)和VFP(场显示后沿)。 RGB LCD液晶屏一般有两种数据同步方式,一种是行场同步模式(HV Mode),另一种是数据使能同步模式(DE Mode)。当选择行场同步模式时,LCD接口的时序与VGA接口的时序图非常相似,只是参数不同,如图 16.1.9和图 16.1.8中的行同步信号(HSYNC)和场同步信号(VSYNC)作为数据的同步信号,此时数据使能信号(DE)必须为低电平。 当选择DE同步模式时,LCD的DE信号作为数据的有效信号,,如图 16.1.10和图 16.1.8中的DE信号所示。只有同时扫描到帧有效显示区域和行有效显示区域时,DE信号才有效(高电平)。当选择DE同步模式时,此时行场同步信号VS和HS必须为高电平。 由于RGB LCD液晶屏一般都支持DE模式,不是所有的RGB LCD液晶屏都支持HV模式,因此本章我们采用DE同步的方式驱动LCD液晶屏。 6、像素时钟 像素时钟就是RGB LCD的时钟信号,以ATK7016这款屏幕为例,显示一帧图像所需要的时钟数就是: N(CLK)= (VSPW+VBP+LINE+VFP) * (HSPW + HBP + HOZVAL + HFP) = (3 + 20 + 600 + 12) * (20 + 140 + 1024 + 160) = 635 * 1344 = 853440 显示一帧图像需要853440个时钟数,那么显示60帧就是:853440 * 60 = 51206400≈51.2M,所以像素时钟就是51.2MHz。 当然我们在为RGB LCD屏提供驱动时钟的时候,也可以不用严格按照60帧来进行计算。为了方便操作,我们可以给ATK7016模块输出一个50MHz的时钟,其刷新率是接近于60Hz的,同时也非常方便我们来编写代码。 为了方便大家查找LCD屏的时序参数,这里整理了不同分辨率的时序参数,如表 18.1.3所示: 表 18.1.3 不同分辨率的LCD时序参数 显示分辨率 时钟(Mhz) 行时序(像素数) 帧时序(行数) 行同步 显示后沿 显示 区域 显示前沿 显示 周期 场同步 显示后沿 显示区域 显示前沿 显示 周期 480272 9 41 2 480 2 525 10 2 272 2 286 800480 33.3 128 88 800 40 1056 2 33 480 10 525 1024600 50 20 140 1024 160 1344 3 20 600 12 635 1280*800 70 10 80 1280 70 1440 3 10 800 10 823 18.2 实验任务 本节的实验任务是使用正点原子ZYNQ开发板上的RGB TFT-LCD接口,驱动RGB LCD液晶屏(支持目前推出的所有RGB LCD屏),并显示出彩条。 18.3 硬件设计 领航者开发板上RGB TFT-LCD接口部分的原理图如下图所示。 在这里插入图片描述

图 7.5.13.1 RGB TFTLCD接口原理图 从上图中可以看到,FPGA管脚输出的颜色数据位宽为24bit,数据格式为RGB888,即数据高8位表示红色,中间8位表示绿色,低8位表示蓝色。由于这24位数据不仅仅作为输出给LCD屏的颜色数据,同时LCD_R7、LCD_G7和LCD_B7也用来获取LCD屏的ID,因此这24位颜色数据对ZYNQ开发板来说,是一个双向的引脚。 另外,RGBLCD模块支持触摸功能,图中以字母T开头的5个信号(T_PEN、T_SCK等)与模块上的触摸芯片相连接。由于本次实验不涉及触摸功能的实现,因此这些信号并未用到。 需要说明的是,LCD液晶屏有一个复位信号(LCD_RST),当LCD_RST为低电平时,可对LCD屏进行复位。 本实验中,各端口信号的管脚分配如下表所示: 表 18.3.1 RGB TFT-LCD彩条实验管脚分配 信号名 方向 管脚 端口说明 电平标准 sys_clk input U18 系统时钟,50M LVCMOS33 sys_rst_n input N16 系统复位,低有效 LVCMOS33 lcd_rgb[0] inout W18 RGB LCD蓝色(最低位) LVCMOS33 lcd_rgb[1] inout W19 RGB LCD蓝色 LVCMOS33 lcd_rgb[2] inout R16 RGB LCD蓝色 LVCMOS33 lcd_rgb[3] inout R17 RGB LCD蓝色 LVCMOS33 lcd_rgb[4] inout W20 RGB LCD蓝色 LVCMOS33 lcd_rgb[5] inout V20 RGB LCD蓝色 LVCMOS33 lcd_rgb[6] inout P18 RGB LCD蓝色 LVCMOS33 lcd_rgb[7] inout N17 RGB LCD蓝色(最高位) LVCMOS33 lcd_rgb[8] inout V17 RGB LCD绿色(最低位) LVCMOS33 lcd_rgb[9] inout V18 RGB LCD绿色 LVCMOS33 lcd_rgb[10] inout T17 RGB LCD绿色 LVCMOS33 lcd_rgb[11] inout R18 RGB LCD绿色 LVCMOS33 lcd_rgb[12] inout Y18 RGB LCD绿色 LVCMOS33 lcd_rgb[13] inout Y19 RGB LCD绿色 LVCMOS33 lcd_rgb[14] inout P15 RGB LCD绿色 LVCMOS33 lcd_rgb[15] inout P16 RGB LCD绿色(最高位) LVCMOS33 lcd_rgb[16] inout V16 RGB LCD红色(最低位) LVCMOS33 lcd_rgb[17] inout W16 RGB LCD红色 LVCMOS33 lcd_rgb[18] inout T14 RGB LCD红色 LVCMOS33 lcd_rgb[19] inout T15 RGB LCD红色 LVCMOS33 lcd_rgb[20] inout Y17 RGB LCD红色 LVCMOS33 lcd_rgb[21] inout Y16 RGB LCD红色 LVCMOS33 lcd_rgb[22] inout T16 RGB LCD红色 LVCMOS33 lcd_rgb[23] inout U17 RGB LCD红色(最高位) LVCMOS33 lcd_hs output N18 RGB LCD行同步 LVCMOS33 lcd_vs output T20 RGB LCD场同步 LVCMOS33 lcd_de output U20 RGB LCD数据使能 LVCMOS33 lcd_bl output M20 RGB LCD背光控制 LVCMOS33 lcd_clk output P19 RGB LCD像素时钟 LVCMOS33 lcd_rst output L17 RGB LCD复位信号 LVCMOS33 对应的XDC约束语句如下所示:

set_property -dict {PACKAGE_PIN U18 IOSTANDARD LVCMOS33} [get_ports sys_clk]
set_property -dict {PACKAGE_PIN N16 IOSTANDARD LVCMOS33} [get_ports sys_rst_n]

set_property -dict {PACKAGE_PIN W18 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[0]}]
set_property -dict {PACKAGE_PIN W19 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[1]}]
set_property -dict {PACKAGE_PIN R16 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[2]}]
set_property -dict {PACKAGE_PIN R17 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[3]}]
set_property -dict {PACKAGE_PIN W20 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[4]}]
set_property -dict {PACKAGE_PIN V20 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[5]}]
set_property -dict {PACKAGE_PIN P18 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[6]}]
set_property -dict {PACKAGE_PIN N17 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[7]}]
set_property -dict {PACKAGE_PIN V17 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[8]}]
set_property -dict {PACKAGE_PIN V18 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[9]}]
set_property -dict {PACKAGE_PIN T17 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[10]}]
set_property -dict {PACKAGE_PIN R18 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[11]}]
set_property -dict {PACKAGE_PIN Y18 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[12]}]
set_property -dict {PACKAGE_PIN Y19 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[13]}]
set_property -dict {PACKAGE_PIN P15 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[14]}]
set_property -dict {PACKAGE_PIN P16 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[15]}]
set_property -dict {PACKAGE_PIN V16 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[16]}]
set_property -dict {PACKAGE_PIN W16 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[17]}]
set_property -dict {PACKAGE_PIN T14 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[18]}]
set_property -dict {PACKAGE_PIN T15 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[19]}]
set_property -dict {PACKAGE_PIN Y17 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[20]}]
set_property -dict {PACKAGE_PIN Y16 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[21]}]
set_property -dict {PACKAGE_PIN T16 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[22]}]
set_property -dict {PACKAGE_PIN U17 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[23]}]

set_property -dict {PACKAGE_PIN N18 IOSTANDARD LVCMOS33} [get_ports lcd_hs]
set_property -dict {PACKAGE_PIN T20 IOSTANDARD LVCMOS33} [get_ports lcd_vs]
set_property -dict {PACKAGE_PIN U20 IOSTANDARD LVCMOS33} [get_ports lcd_de]
set_property -dict {PACKAGE_PIN M20 IOSTANDARD LVCMOS33} [get_ports lcd_bl]
set_property -dict {PACKAGE_PIN P19 IOSTANDARD LVCMOS33} [get_ports lcd_clk]
set_property -dict {PACKAGE_PIN L17 IOSTANDARD LVCMOS33} [get_ports lcd_rst]

18.4 程序设计 RGB TFT-LCD输入时序包含三个要素:像素时钟、同步信号、以及图像数据,由此我们可以大致规划出系统结构如下图所示。其中,读取ID模块用于获取LCD屏的ID;由于不同分辨率的屏幕需要不同的驱动时钟,因此时钟分频模块根据LCD ID来输出不同频率的像素时钟;LCD显示模块负责产生液晶屏上显示的数据,即彩条数据;LCD驱动模块根据LCD屏的ID,输出不同参数的时序,来驱动LCD屏,并将输入的彩条数据显示到LCD屏上。 在这里插入图片描述

图 7.5.13.1 RGB TFT-LCD彩条显示系统框图 由系统框图可知,FPGA部分包括五个模块,顶层模块(lcd_rgb_colorbar)、读取ID模块(rd_id)、时钟分频模块(clk_div)、LCD显示模块(lcd_display)以及LCD驱动模块(lcd_driver)。其中在顶层模块中完成对其余模块的例化。 各模块端口及信号连接如下图所示: 在这里插入图片描述

图 7.5.13.2 顶层模块原理图 读取ID模块(rd_id)在上电时将RGB双向数据总线设置为输入,来读取LCD屏的ID;时钟分频模块(clk_div)根据读取的ID来配置LCD的像素时钟;LCD驱动模块(lcd_driver)在像素时钟的驱动下输出数据使能信号用于数据同步,同时还输出像素点的纵横坐标,供LCD显示模块(lcd_display)调用,以绘制彩条图案。 顶层模块lcd_rgb_colorbar的代码如下:

1  module lcd_rgb_colorbar(
2      input                sys_clk,     //系统时钟
3      input                sys_rst_n,   //系统复位
4  
5      //RGB LCD接口
6      output               lcd_de,      //LCD 数据使能信号
7      output               lcd_hs,      //LCD 行同步信号
8      output               lcd_vs,      //LCD 场同步信号
9      output               lcd_bl,      //LCD 背光控制信号
10     output               lcd_clk,     //LCD 像素时钟
11     output               lcd_rst,     //LCD 复位
12     inout        [23:0]  lcd_rgb      //LCD RGB888颜色数据
13     );                                                      
14     
15 //wire define    
16 wire  [15:0]  lcd_id    ;    //LCD屏ID
17 wire          lcd_pclk  ;    //LCD像素时钟
18               
19 wire  [10:0]  pixel_xpos;    //当前像素点横坐标
20 wire  [10:0]  pixel_ypos;    //当前像素点纵坐标
21 wire  [10:0]  h_disp    ;    //LCD屏水平分辨率
22 wire  [10:0]  v_disp    ;    //LCD屏垂直分辨率
23 wire  [23:0]  pixel_data;    //像素数据
24 wire  [23:0]  lcd_rgb_o ;    //输出的像素数据
25 wire  [23:0]  lcd_rgb_i ;    //输入的像素数据
26 
27 //*****************************************************
28 //**                    main code
29 //*****************************************************
30 
31 //像素数据方向切换
32 assign lcd_rgb = lcd_de ?  lcd_rgb_o :  {24{1'bz}};
33 assign lcd_rgb_i = lcd_rgb;
34 
35 //读LCD ID模块
36 rd_id u_rd_id(
37     .clk          (sys_clk  ),
38     .rst_n        (sys_rst_n),
39     .lcd_rgb      (lcd_rgb_i),
40     .lcd_id       (lcd_id   )
41     );    
42 
43 //时钟分频模块    
44 clk_div u_clk_div(
45     .clk           (sys_clk  ),
46     .rst_n         (sys_rst_n),
47     .lcd_id        (lcd_id   ),
48     .lcd_pclk      (lcd_pclk )
49     );    
50 
51 //LCD显示模块    
52 lcd_display u_lcd_display(
53     .lcd_pclk       (lcd_pclk  ),
54     .rst_n          (sys_rst_n ),
55     .pixel_xpos     (pixel_xpos),
56     .pixel_ypos     (pixel_ypos),
57     .h_disp         (h_disp    ),
58     .v_disp         (v_disp    ),
59     .pixel_data     (pixel_data)
60     );    
61 
62 //LCD驱动模块
63 lcd_driver u_lcd_driver(
64     .lcd_pclk      (lcd_pclk  ),
65     .rst_n         (sys_rst_n ),
66     .lcd_id        (lcd_id    ),
67     .pixel_data    (pixel_data),
68     .pixel_xpos    (pixel_xpos),
69     .pixel_ypos    (pixel_ypos),
70     .h_disp        (h_disp    ),
71     .v_disp        (v_disp    ),
72 
73     .lcd_de        (lcd_de    ),
74     .lcd_hs        (lcd_hs    ),
75     .lcd_vs        (lcd_vs    ),
76     .lcd_bl        (lcd_bl    ),
77     .lcd_clk       (lcd_clk   ),
78     .lcd_rst       (lcd_rst   ),
79     .lcd_rgb       (lcd_rgb_o )
80     );
81 
82 endmodule

顶层模块主要完成对其他模块的例化。这里需要重点注意第32行代码,由于lcd_rgb是24位的双向引脚,所以这里对双向引脚的方向做一个切换。当lcd_de信号为高电平时,此时输出的像素数据有效,将lcd_rgb的引脚方向切换成输出,并将LCD驱动模块输出的lcd_rgb_o(像素数据)连接至lcd_rgb引脚;当lcd_de信号为低电平时,此时输出的像素数据无效,将lcd_rgb的引脚方向切换成输入。代码中将高阻状态“Z”赋值给lcd_rgb的引脚,表示此时lcd_rgb的引脚电平由外围电路决定,此时可以读取lcd_rgb的引脚电平,从而获取到LCD屏的ID。 读取ID模块的代码如下:

1   module rd_id(
2       input                   clk    ,    //时钟
3       input                   rst_n  ,    //复位,低电平有效
4       input           [23:0]  lcd_rgb,    //RGB LCD像素数据,用于读取ID
5       output   reg    [15:0]  lcd_id      //LCD屏ID
6       );
7   
8   //reg define
9   reg            rd_flag;                 //读ID标志
10  
11  //*****************************************************
12  //**                    main code
13  //*****************************************************
14  
15  //获取LCD ID   M2:B7  M1:G7  M0:R7
16  always @(posedge clk or negedge rst_n) begin
17      if(!rst_n) begin
18          rd_flag             
关注
打赏
1665308814
查看更多评论
0.0400s