1. LCD工作的硬件需求:
要使一块LCD正常的显示文字或图像,不仅需要LCD驱动器,而且还需要相应的LCD控制器。在通常情况下,生产厂商把LCD驱动器会以 COF/COG的 形式与LCD玻璃基板制作在一起,而LCD控制器则是由外部的电路来实现,现在很多的MCU内部都集成了LCD控制器,如S3C2410/2440等。通 过LCD控制器就可以产生LCD驱动器所需要的控制信号来控制STN/TFT屏了。
2. S3C2440内部LCD控制器结构图:
我们根据数据手册来描述一下这个集成在S3C2440内部的LCD控制器:
a:LCD控制器由REGBANK、LCDCDMA、TIMEGEN、VIDPRCS寄存器组成;
b:REGBANK由17个可编程的寄存器组和一块256*16的调色板内存组成,它们用来配置LCD控制器的;
c:LCDCDMA是一个专用的DMA,它能自动地把在侦内存中的视频数据传送到LCD驱动器,通过使用这个DMA通道,视频数据在不需要CPU的干预的情况下显示在LCD屏上;
d:VIDPRCS接收来自LCDCDMA的数据,将数据转换为合适的数据格式,比如说4/8位单扫,4位双扫显示模式,然后通过数据端口VD[23:0]传送视频数据到LCD驱动器;
e:TIMEGEN由 可编程的逻辑组成,他生成LCD驱动器需要的控制信号,比如VSYNC、HSYNC、VCLK和LEND等,而这些控制信号又与REGBANK寄存器组中 的LCDCON1/2/3/4/5的配置密切相关,通过不同的配置,TIMEGEN就能产生这些信号的不同形态,从而支持不同的LCD驱动器(即不同的 STN/TFT屏)。
FIFO存储器位于LCDCDMA.。当FIFO空或部分空时,LCDCDMA要求从帧缓冲中取来要显示的图像数据,而这个帧缓冲是LCD控制 器在RAM中开辟的一片缓冲区。当这个传输请求被存储控制器中的总线仲裁器接收到后,从系统存储器到内部FIFO就会成功传输4个字节。FIFO的总大小 是28个字,其中低位FIFOL是12个字,高位FIFOH是16个字。
3. 常见TFT屏工作时序分析:
LCD提供的外部接口信号:
VSYNC/VFRAME/STV:垂直同步信号(TFT)/帧同步信号(STN)/SEC TFT信号;
HSYNC/VLINE/CPV:水平同步信号(TFT)/行同步脉冲信号(STN)/SEC TFT信号;
VCLK/LCD_HCLK:象素时钟信号(TFT/STN)/SEC TFT信号;
VD[23:0]:LCD像素数据输出端口(TFT/STN/SEC TFT);
VDEN/VM/TP:数据使能信号(TFT)/LCD驱动交流偏置信号(STN)/SEC TFT 信号;
LEND/STH:行结束信号(TFT)/SEC TFT信号;
LCD_LPCOE:SEC TFT OE信号;
LCD_LPCREV:SEC TFT REV信号;
LCD_LPCREVB:SEC TFT REVB信号。
所有显示器显示图像的原理都是从上到下,从左到右的。这是什么意思呢?这么说吧,一副图像可以看做是一个矩形,由很多排列整齐的点一行一行组成,这些点称之为像素。那么这幅图在LCD上的显示原理就是:
A:显示指针从矩形左上角的第一行第一个点开始,一个点一个点的在LCD上显示,在上面的时序图上用时间线表示就为VCLK,我们称之为像素时钟信号;
B:当显示指针一直显示到矩形的右边就结束这一行,那么这一行的动作在上面的时序图中就称之为1 Line;
C:接下来显示指针又回到矩形的左边从第二行开始显示,注意,显示指针在从第一行的右边回到第二行的左边是需要一定的时间的,我们称之为行切换;
D:如此类推,显示指针就这样一行一行的显示至矩形的右下角才把一副图显示完成。因此,这一行一行的显示在时间线上看,就是时序图上的HSYNC;
E: 然 而,LCD的显示并不是对一副图像快速的显示一下,为了持续和稳定的在LCD上显示,就需要切换到另一幅图上(另一幅图可以和上一副图一样或者不一样,目 的只是为了将图像持续的显示在LCD上)。那么这一副一副的图像就称之为帧,在时序图上就表示为1 Frame,因此从时序图上可以看出1 Line只是1 Frame中的一行;
F:同样的,在帧与帧切换之间也是需要一定的时间的,我们称之为帧切换,那么LCD整个显示的过程在时间线上看,就可表示为时序图上的VSYNC。
上面时序图上各时钟延时参数的含义如下:(这些参数的值,LCD产生厂商会提供相应的数据手册)
VBPD(vertical back porch):表示在一帧图像开始时,垂直同步信号以后的无效的行数,对应驱动中的upper_margin;
VFBD(vertical front porch):表示在一帧图像结束后,垂直同步信号以前的无效的行数,对应驱动中的lower_margin;
VSPW(vertical sync pulse width):表示垂直同步脉冲的宽度,用行数计算,对应驱动中的vsync_len;
HBPD(horizontal back porch):表示从水平同步信号开始到一行的有效数据开始之间的VCLK的个数,对应驱动中的left_margin;
HFPD(horizontal front porth):表示一行的有效数据结束到下一个水平同步信号开始之间的VCLK的个数,对应驱动中的right_margin;
HSPW(horizontal sync pulse width):表示水平同步信号的宽度,用VCLK计算,对应驱动中的hsync_len;
注:对于一个已知尺寸的LCD屏,只要确定了VCLK值,行频和场频就应该知道了。但这样还不行的,因为在每一帧时钟信号中,还会有一些与屏显示无关的时钟出现,这就给确定行频和场频带来了一定的复杂性。如在HSYNC信号先后会有水平同步信号前肩(HFPD)和水平同步信号后肩(HBPD)出现,在VSYNC信号先后会有垂直同步信号前肩(VFPD)和垂直同步信号后肩(VBPD)出现,在这些信号时序内,不会有有效像素信号出现,另外HSYNC和VSYNC信号有效时,其电平要保持一定的时间,它们分别叫做水平同步信号脉宽HSPW和垂直同步信号脉宽VSPW,这段时间也不能有像素信号。因此计算行频和场频时,一定要包括这些信号。
[page]
4. 帧缓冲(FrameBuffer):
帧缓冲是Linux为显示设备提供的一个接口,它把一些显示设备描述成一个缓冲区,允许应用程序通过 FrameBuffer定义好的接口访问这些图形设备,从而不用去关心具体的硬件细节。对于帧缓冲设备而言,只要在显示缓冲区与显示点对应的区域写入颜色 值,对应的颜色就会自动的在屏幕上显示。下面来看一下在不同色位模式下缓冲区与显示点的对应关系:
volatile static unsigned short LCD_BUFFER[240][320];
void Pixel(U32 x,U32 y, U16 c )
{
if ( (x < SCR_XSIZE_TFT_320240) && (y < SCR_YSIZE_TFT_320240) )
LCD_BUFFER[y][x] = c;
}
很容易发现TFT LCD上显示单个像素的函数实际上很简洁,看来似乎只需要LCD_BUFFER[(y)][(x)] = c这一句话.下面就来分析下,是如何通过这一句话来实现在LCD上显示单个像素的,先分析下Lcd_Init()即LCD初始化函数:
#define rGPCCON
#define rGPCUP
#define rGPDCON
#define rGPDUP
#define rLCDCON1
#define rLCDCON2
#define rLCDCON3
#define rLCDCON4
#define rLCDCON5
#define rLCDSADDR1
#define rLCDSADDR2
#define rLCDSADDR3
#define rLCDINTMSK
#define rTPAL
void Lcd_Init(void)
{
}
程序分析至此,大概已经清楚是如何通过LCD_BUFFER[(y)][(x)] = c来实现在LCD上显示单个像素了。就是在设置好各个LCD寄存器之后,通过将LCD_BUFFER地址与LCDBANK以及LCDBASEU、 LCDBASEL对应之后,通过改变LCD_BUFFER里不同单元存储的值(即像素的颜色),即可在LCD相应位置上做出显示。
那么在应用不同LCD的时候,只需对LCDCONx以及LCDSADDRx做出相应的配置,再创建一个数组,做出上述的地址映射即可。
关于VCLK计算,由于配置的是TFT,可用到公式VCLK = HCLK / [(CLKVAL+1) * 2] ( CLKVAL>=0 ),设置的Fclk为400MHz,Hclk为100MHz(Fclk:Hclk=1:4),CLKVAL = 4,因此VLCK = 10MHz。
笔记:
首先说一下我们平时所说的多少位的LCD,有24位的,有16位的指的是LCD数据的位数,LCD的数据实际上是LCD要显示的颜色,24位的是红绿 蓝各占8位,16位则是红绿蓝按照565分配的,其实24的也可以只接16位,每个颜色地位接地就可以,所以要给LCD的缓冲区一个数据才能在LCD上显 示出来。那究竟是怎么显示的呢,那就得先说一下像素了,LCD的像素实际上就LCD屏幕有多少个点,LCD显示的东西都是一个一个点拼凑出来的,比如我用 的是320*240的LCD,就是说LCD每一行有320个点,而每一列有240个点,所以总共有320*240个点,我们让适当的点显示适当的颜色就达 到了我们的目的。
其实刚开始困扰我们的是LCD的初始化的问题,要设置的东西比较多,其实我们是记不住这些东西的,呵呵,作为入门我们可以参考别人的初始化程序,把里面的参数改成我们自己的LCD的参数就OK了。
那么我们到底是怎么把我们要显示的数据送给LCD控制起的呢?是这样的,我们可以定义一个二维数组,把我们要显示的数据存到里面,然后把这个数组的地 址赋给LCD的相应的寄存器,这个寄存器是LCDSADDRn,具体的设置大家可以参考数据手册,我们可以把二维数组的坐标和LCD的坐标对应起来,那么 我们就可以随意的让哪一个像素点显示什么颜色就显示什么颜色了。这就把数据送出的过程,也就是显示一个像素点的过程。
到现在我们已经知道如何显示一个像素了,那接下来就是LCD显示最基本的东西了----字符和图片。汉字和图片的显示都是基于像素点的显示的,我们把 要显示的字符和图片转化成相应的数据,然后传递给LCD即可。我们可以专门的写一个显示字符的函数和一个显示图片的函数。显示字符的数据可以用取模软件生 成,因为生成的字符数据是表示的每一个点要不要亮,亮的地方用1表示,不亮的地方用0表示,所以如果用LCD显示,我们还要告诉LCD显示什么颜色,这才 是LCD需要的数据,比如说16*16的数据,有16行16列,我们将一行的数据,也就是16位数据的每一位都取出来,为1的地方,我们就给LCD一个 16位的数据,为0的地方就不给数据,这样就能显示了,取模生成的数据都是按行来的。图片的显示直接就将16位的数据传递给LCD,这个图片数据的产生, 我们可以用软件LCD彩色图片转换工具(BMP_to_H)生成C语言文件,我们只需对文件进行简单的修改就能加入到我们的程序中,修改方法在软件的说明 中都有。
编程要点:
1、打开LCD背光
将LCD背光对应的GPIO设置为禁止上拉(GPxUP相应位写入1),选择output类型(GPxCON相应位写入01),输出为高电平(GPxDAT相应位写入1)。
2、打开LCD电源
可以将GPG4选择为LCD_PWREN(GPGCON:9-8写入11),这时候LCD电源的打开/关闭可以通过LCDCON5:3来控制。也可以自定 义其他GPIO用作LCD电源开关,只需将此GPIO设置为禁止上拉(GPxUP相应位写入1),选择output类型(GPxCON相应位写入01), 输出为高电平(GPxDAT相应位写入1)打开LCD电源。
3、设置其他信号线
其他信号线包括VD0-VD23和VFRAME、VLINE、VCLK等,分别在GPCCON,GPDCON中选择相应功能。
4、设置LCD的频率(VCLK)
LCD的Datasheet上一般会写有一个推荐的频率,比如我使用的屏幕推荐频率为6.4M,我需要通过一些计算选择一个合适的CLKVAL以产生这个频率:
对于TFT LCD,S3C2440提供的VCLK的计算公式为:VCLK = HCLK / ((CLKVAL+1)*2)
可以得出:CLKVAL = HCLK / (VCLK * 2) - 1
我 的HCLK是100Mhz(CPU运行在400Mhz, CLKDIV_VAL设置为5,Fclk:Hclk:Pclk = 1:4:8),VCLK使用屏幕推荐的6.4M,得到:CLKVAL = 100000000 / (6400000 * 2) - 1 = 6.8
选择最接近的整数值7,写入LCDCON1:17-8。
(VCLK其实就是根据 每秒帧数*帧行数*行像素 计算出来的,帧行数和行像素需要包含空白数和同步数)
5、设置其他相关参数
LCD相关的参数主要还有这几个:LINEVAL: LCD水平像素-1,如320-1 = 319HOZVAL: LCD垂直像素-1,如240-1 = 239HFPD: 行开始前的VCLK时钟数(LCD屏幕的Datasheet一般有推荐值)HBPD: 行结束后的VCLK时钟数(LCD屏幕的Datasheet一般有推荐值)HSPW: 行之间水平同步的无效VCLK时钟数(LCD屏幕的Datasheet一般有推荐值)VFPD: 帧数据开始前的空白行数(LCD屏幕的Datasheet一般有推荐值)VBPD: 帧数据结束后的空白行数(LCD屏幕的Datasheet一般有推荐值)VSPW: 帧之间垂直同步的无效行数(LCD屏幕的Datasheet一般有推荐值)
(相关寄存器LCDCON2, LCDCON3, LCDCON4)
6、设置视频缓冲区的地址
2440支持虚拟屏幕,可以通过改变LCD寄存器实现屏幕快速移动:
PAGEWIDTH:虚拟屏幕一行的字节数,如果不使用虚拟屏幕,设置为实际屏幕的行字节数,如16位宽320像素,设为320 * 2OFFSIZE:虚拟屏幕左侧偏移的字节数,如果不使用虚拟屏幕,设置为0
LCDBANK: 视频帧缓冲区内存地址30-22位LCDBASEU: 视频帧缓冲区的开始地址21-1位LCDBASEL: 视频帧缓冲区的结束地址21-1位
(相关寄存器LCDSADDR1,LCDSADDR2,LCDSADDR3)
7、确定信号的极性
2440的LCD控制器允许设置VCLK、VLINE、VFRAME等信号的极性(上升沿有效还是下降沿有效),需要对照LCD的Datasheet一一确认。
(相关寄存器LCDCON5)
8、禁止LPC3600/LCC3600模式
如果不是使用三星LPC3600/LCC3600 LCD,必须禁止LPC3600/LCC3600模式(写入0到TCONSEL)。
上一篇:uboot如何检测s3c2440是从Nand Flash还是Nor Flash启动
下一篇:S3C2440裸奔触摸屏
推荐阅读最新更新时间:2024-03-16 14:31
设计资源 培训 开发板 精华推荐
- 直播已结束|Molex 和 TTI 更小型、高速、可靠的连接器推动物联网应用的新发展
- Mouser 新用户大礼包:你购物,我5折返E金币!
- 任选下载有礼| ADI 【锂电池解决方案、参考电路合集】
- 分享赢开发板:告诉小伙伴,2018年ST全国巡回研讨会开始啦
- 技术直播:TI 60G毫米波传感器概述和应用介绍,种草封装了天线的智能传感器IWR6843
- 下载Mentor白皮书,迎接电路板与晶片日益复杂的设计挑战,还有好礼相送哟!
- 阅读是德科技 Power Supply、汽车电子精彩专题,让您的设计更精准!参与答题赢好礼!
- 绝地求生,集齐4样必然吃鸡!览TI汽车技术方案 赢小礼品
- 带你零起点入门STM32(专为嵌入式应用而开发的内核)