ARM9S3C2440之六LCD显示.docx

上传人:b****5 文档编号:6696123 上传时间:2023-01-09 格式:DOCX 页数:14 大小:120.11KB
下载 相关 举报
ARM9S3C2440之六LCD显示.docx_第1页
第1页 / 共14页
ARM9S3C2440之六LCD显示.docx_第2页
第2页 / 共14页
ARM9S3C2440之六LCD显示.docx_第3页
第3页 / 共14页
ARM9S3C2440之六LCD显示.docx_第4页
第4页 / 共14页
ARM9S3C2440之六LCD显示.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

ARM9S3C2440之六LCD显示.docx

《ARM9S3C2440之六LCD显示.docx》由会员分享,可在线阅读,更多相关《ARM9S3C2440之六LCD显示.docx(14页珍藏版)》请在冰豆网上搜索。

ARM9S3C2440之六LCD显示.docx

ARM9S3C2440之六LCD显示

六  ARM9(S3C2440)的LCD显示——理论知识

转载自:

骨Zi里德骄傲

   今天和大家一起讨论一下S3C2440的LCD显示的问题,希望大家能够多多指教,我说的不对的地方希望大家及时帮我改正,以使我可以增长知识,才能不至于给别人的学习带来不便,呵呵

下面先看一下我从别人那转过来的一篇文章,我觉得很有用,看完之后我再说一下自己对这一块的了解,也可以先看看我的理解(下面红字标出)再看开始的这篇文章,因为我说的更通俗,O(∩_∩)O哈哈~。

   

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屏)。

 

3.常见TFT屏工作时序分析:

 

 

LCD提供的外部接口信号:

 

VSYNC/VFRAME/STV:

垂直同步信号(TFT)/帧同步信号(STN)/SECTFT信号;

HSYNC/VLINE/CPV:

水平同步信号(TFT)/行同步脉冲信号(STN)/SECTFT信号;

VCLK/LCD_HCLK:

象素时钟信号(TFT/STN)/SECTFT信号;

VD[23:

0]:

LCD像素数据输出端口(TFT/STN/SECTFT);

VDEN/VM/TP:

数据使能信号(TFT)/LCD驱动交流偏置信号(STN)/SECTFT信号;

LEND/STH:

行结束信号(TFT)/SECTFT信号;

LCD_LPCOE:

SECTFTOE信号;

LCD_LPCREV:

SECTFTREV信号;

LCD_LPCREVB:

SECTFTREVB信号。

 

所有显示器显示图像的原理都是从上到下,从左到右的。

这是什么意思呢?

这么说吧,一副图像可以看做是一个矩形,由很多排列整齐的点一行一行组成,这些点称之为像素。

那么这幅图在LCD上的显示原理就是:

 

A:

显示指针从矩形左上角的第一行第一个点开始,一个点一个点的在LCD上显示,在上面的时序图上用时间线表示就为VCLK,我们称之为像素时钟信号;

B:

当显示指针一直显示到矩形的右边就结束这一行,那么这一行的动作在上面的时序图中就称之为1Line;

C:

接下来显示指针又回到矩形的左边从第二行开始显示,注意,显示指针在从第一行的右边回到第二行的左边是需要一定的时间的,我们称之为行切换;

D:

如此类推,显示指针就这样一行一行的显示至矩形的右下角才把一副图显示完成。

因此,这一行一行的显示在时间线上看,就是时序图上的HSYNC;

E:

然而,LCD的显示并不是对一副图像快速的显示一下,为了持续和稳定的在LCD上显示,就需要切换到另一幅图上(另一幅图可以和上一副图一样或者不一样,目的只是为了将图像持续的显示在LCD上)。

那么这一副一副的图像就称之为帧,在时序图上就表示为1Frame,因此从时序图上可以看出1Line只是1Frame中的一行;

F:

同样的,在帧与帧切换之间也是需要一定的时间的,我们称之为帧切换,那么LCD整个显示的过程在时间线上看,就可表示为时序图上的VSYNC。

 

上面时序图上各时钟延时参数的含义如下:

(这些参数的值,LCD产生厂商会提供相应的数据手册)

 

VBPD(verticalbackporch):

表示在一帧图像开始时,垂直同步信号以后的无效的行数,对应驱动中的upper_margin;

VFBD(verticalfrontporch):

表示在一帧图像结束后,垂直同步信号以前的无效的行数,对应驱动中的lower_margin;

VSPW(verticalsyncpulsewidth):

表示垂直同步脉冲的宽度,用行数计算,对应驱动中的vsync_len;

HBPD(horizontalbackporch):

表示从水平同步信号开始到一行的有效数据开始之间的VCLK的个数,对应驱动中的left_margin;

HFPD(horizontalfrontporth):

表示一行的有效数据结束到下一个水平同步信号开始之间的VCLK的个数,对应驱动中的right_margin;

HSPW(horizontalsyncpulsewidth):

表示水平同步信号的宽度,用VCLK计算,对应驱动中的hsync_len;

 

对于以上这些参数的值将分别保存到REGBANK寄存器组中的LCDCON1/2/3/4/5寄存器中:

(对寄存器的操作请查看S3c2440数据手册LCD部分)

 

LCDCON1:

17 -8位CLKVAL

6 -5位扫描模式(对于STN屏:

4位单/双扫、8位单扫)

4 -1位色位模式(1BPP、8BPP、16BPP等)

LCDCON2:

31-24位VBPD

23-14位LINEVAL

13-6位VFPD

5-0位VSPW

LCDCON3:

25-19位HBPD

18-8位HOZVAL

7-0位HFPD

LCDCON4:

7-0位HSPW

LCDCON5:

 

4.帧缓冲(FrameBuffer):

  帧缓冲是Linux为显示设备提供的一个接口,它把一些显示设备描述成一个缓冲区,允许应用程序通过FrameBuffer定义好的接口访问这些图形设备,从而不用去关心具体的硬件细节。

对于帧缓冲设备而言,只要在显示缓冲区与显示点对应的区域写入颜色值,对应的颜色就会自动的在屏幕上显示。

下面来看一下在不同色位模式下缓冲区与显示点的对应关系:

 

我相信看完这些以后大家会对这一块有稍一些了解了,下面是我自己的理解:

  LCD是在我们学习ARM9时觉得比较麻烦的一块,因为刚接触的时候一眼望去觉得内容可是不少,不知道从哪里下手,呵呵,其实我们慢慢来分析就会逐渐明朗起来。

  首先说一下我们平时所说的多少位的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语言文件,我们只需对文件进行简单的修改就能加入到我们的程序中,修改方法在软件的说明中都有。

 

  以上这些都是我自己的理解,话虽然不多,但这些都是我刚开始学的时候困扰我的地方,我相信看了这些对你理解LCD到底是怎样显示的会有一定的帮助,说的不对的地方,请大家及时帮我改正,呵呵。

  下一篇文章中我将结合具体的代码分析一下LCD的操作过程。

结合上一篇文章中的LCD理论知识,下面是结合FL2440开发板的实例程序,所用的LCD是16位320*240

操作的大概步骤是先初始化LCD,然后是写我们所需要的函数,最基础的是像素点显示函数,然后是划线函数,字符显示函数,图片显示函数等等,然后就是写主函数完成我们的任务。

#include"def.h"

#include"option.h"

#include"2440addr.h"

#include"2440lib.h"

#include"2440slib.h"

#defineMVAL  (13)//定义的宏方便后面的设置操作

#defineMVAL_USED (0)  //0=eachframe  1=ratebyMVAL

#defineINVVDEN  

(1)  //0=normal      1=inverted

#defineBSWP  (0)  //Byteswapcontrol

#defineHWSWP  

(1)  //Halfwordswapcontrol

#defineM5D(n)((n)&0x1fffff) //Togetlower21bits

//TFT320240

#defineLCD_XSIZE_TFT_320240 (320)//定义LCD尺寸,是按像素来的

#defineLCD_YSIZE_TFT_320240 (240)

//TFT320240

#defineSCR_XSIZE_TFT_320240 (320)//X尺寸

#defineSCR_YSIZE_TFT_320240 (240)//Y尺寸

//TFT320240

#defineHOZVAL_TFT_320240 (LCD_XSIZE_TFT_320240-1)//分辨率 可以参考数据手册,就是这样设置的要减1

#defineLINEVAL_TFT_320240 (LCD_YSIZE_TFT_320240-1)

//TimingparameterforLCDLQ035Q7DB02

#defineVBPD_320240  (3)  //垂直同步信号的后肩

#defineVFPD_320240  (5)  //垂直同步信号的前肩

#defineVSPW_320240  (15)  //垂直同步信号的脉宽

#defineHBPD_320240  (58)  //水平同步信号的后肩 5

#defineHFPD_320240  (15)  //水平同步信号的前肩

#defineHSPW_320240  (8)  //水平同步信号的脉宽

#defineCLKVAL_TFT_320240 (9)// 10

//FCLK=180MHz,HCLK=90MHz,VCLK=6.5MHz

externunsignedchartu[];//这就是由软件转化的图片数据,是加入到工程中的C语言文件

volatilestaticunsignedshortLCD_BUFFER[SCR_YSIZE_TFT_320240][SCR_XSIZE_TFT_320240];//数据缓冲区

unsignedcharnian1616[]={0x08,0x00,0x0F,0xFC,0x10,0x80,0x10,0x80,0x20,0x80,0x4F,0xF8,0x88,0x80,0x08,0x80,

0x08,0x80,0x08,0x80,0xFF,0xFE,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80

};//年//取模软件生成的字符数据

unsignedcharnian2424[]={0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x80,0x00,0x03,0x00,0x00,0x06,0x00,0x08,0x07,

0xFF,0xFC,0x0C,0x08,0x00,0x08,0x08,0x00,0x10,0x08,0x00,0x20,0x08,0x20,0x46,0x08,

0x70,0x07,0xFF,0x80,0x06,0x08,0x00,0x06,0x08,0x00,0x06,0x08,0x00,0x06,0x08,0x0C,

0x39,0xFF,0xF0,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x0C,0x00,0x00,

0x0C,0x00,0x00,0x0C,0x00,0x00,0x00,0x00};

unsignedcharyue2424[]={0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x20,0x01,0xFF,0xF0,0x01,0x00,0x20,0x01,

0x00,0x20,0x01,0x00,0x20,0x01,0x00,0x20,0x01,0xFF,0xE0,0x01,0x00,0x20,0x01,0x00,

0x20,0x01,0x00,0x20,0x01,0x00,0x20,0x01,0x00,0x20,0x01,0xFF,0xE0,0x01,0x00,0x20,

0x01,0x00,0x20,0x03,0x00,0x20,0x02,0x00,0x20,0x06,0x00,0x20,0x04,0x04,0x60,0x08,

0x03,0xE0,0x10,0x00,0xC0,0x00,0x00,0x00};

unsignedcharyue1616[]={0x07,0xF0,0x04,0x10,0x04,0x10,0x04,0x10,0x07,0xF0,0x04,0x10,0x04,0x10,0x04,0x10,

0x07,0xF0,0x04,0x10,0x08,0x10,0x08,0x10,0x10,0x10,0x20,0x50,0x40,0x20,0x00,0x00};//月

unsignedcharri1616[]={0x00,0x00,0x1F,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x1F,0xF0,0x10,0x10,

0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x1F,0xF0,0x10,0x10,0x00,0x00,0x00,0x00};//日

staticvoidLcd_Init(void)

{

   rGPCUP=0xffffffff;//DisablePull-upregister

   rGPCCON=0xaaaa56a9;//InitializeVD[7:

0],LCDVF[2:

0],VM,VFRAME,VLINE,VCLK,LEND

   rGPDUP=0xffffffff;//DisablePull-upregister

   rGPDCON=0xaaaaaaaa;//InitializeVD[15:

8]

 rLCDCON1=(CLKVAL_TFT_320240<<8)|(MVAL_USED<<7)|(3<<5)|(12<<1)|0;

    //TFTLCDpanel,12bppTFT,ENVID=off

 rLCDCON2=(VBPD_320240<<24)|(LINEVAL_TFT_320240<<14)|(VFPD_320240<<6)|(VSPW_320240);

 rLCDCON3=(HBPD_320240<<19)|(HOZVAL_TFT_320240<<8)|(HFPD_320240);

 rLCDCON4=(MVAL<<8)|(HSPW_320240);

 rLCDCON5=(1<<11)|(1<<9)|(1<<8)|(1<<3)|(BSWP<<1)|(HWSWP);

 //rLCDCON5=(1<<11)|(0<<9)|(0<<8)|(0<<6)|(BSWP<<1)|(HWSWP); //FRM5:

6:

5,HSYNCandVSYNCareinverted

 rLCDSADDR1=(((U32)LCD_BUFFER>>22)<<21)|M5D((U32)LCD_BUFFER>>1);

 rLCDSADDR2=M5D(((U32)LCD_BUFFER+(SCR_XSIZE_TFT_320240*LCD_YSIZE_TFT_320240*2))>>1);

 rLCDSADDR3=(((SCR_XSIZE_TFT_320240-LCD_XSIZE_TFT_320240)/1)<<11)|(LCD_XSIZE_TFT_320240/1);

 rLCDINTMSK|=(3);//MASKLCDSubInterrupt

   //rTCONSEL|=((1<<4)|1);//DisableLCC3600,LPC3600

 rTPAL=0;//DisableTempPalette

}

staticvoidLcd_EnvidOnOff(intonoff)

{

   if(onoff==1)

 rLCDCON1|=1;//ENVID=ON

   else

 rLCDCON1=rLCDCON1&0x3fffe;//ENVIDOff

}

staticvoidLcd_PowerEnable(intinvpwren,intpwren)

{

   //GPG4issettedasLCD_PWREN

   rGPGUP=rGPGUP&(~(1<<4))|(1<<4);//Pull-updisable

   rGPGCON=rGPGCON&(~(3<<8))|(3<<8);//GPG4=LCD_PWREN

   //EnableLCDPOWERENABLEFunction

   rLCDCON5=rLCDCON5&(~(1<<3))|(pwren<<3);  //PWREN

   rLCDCON5=rLCDCON5&(~(1<<5))|(invpwren<<5);  //INVPWREN

}

staticvoidPutPixel(U32x,U32y,U32c)//实际上c在这是16位数据,即是三种颜色调成的颜色数据

{

 if((x

  LCD_BUFFER[(y)][(x)]=c;//在指定的位置显示指定的颜色

}

staticvoidLcd_ClearScr(U32c)

{

 unsignedintx,y;

  

   for(y=0;y

   {

    for(x=0;x

    {

   LCD_BUFFER[y][x]=c;

    }

   }

}

 

staticvoidGlib_Rectangle(intx1,inty1,intx2,inty2,intcolor)

{

   Glib_Line(x1,y1,x2,y1,color);

   Glib_Line(x2,y1,x2,y2,color);

   Glib_Line(x1,y2,x2,y2,color);

   Glib_Line(x1,y1,x1,y2,color);

}

staticvoidGlib_FilledRectangle(intx1,inty1,intx2,inty2,intcolor)

{

   inti;

   for(i=y1;i<=y2;i++)

 Glib_Line(x1,i,x2,i,color);

}

staticvoidPaint_Bmp(intx0,inty0,inth,intl,unsignedcharbmp[])

{

 intx,y;

 U32c;

 intp=0;

 

   for(y=y0;y

   {

    for(x=x0;x

    {

     c=bmp[p+1]|(bmp[p]<<8);//将文件中的数据转化成16位的数据

   if(((x0+x)

    LCD_BUFFER[y0+y][x0+x]=c;

   

     p=p+2;

    }

   }

}

voidDraw_Text16(intx,inty,intcolor,unsignedcharch[])//显示16*16汉字

{

      unsignedshortinti,j;

      unsignedc

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 医药卫生 > 基础医学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1