S3C2440LCD控制器与TFT屏的字符和图片的显示

来源:互联网 发布:t2雷霆机甲数据 编辑:程序博客网 时间:2024/04/30 18:47
 

2440LCD控制器与TFT屏的总结

一、       学习前的困惑

从刚学2440到现在也有一个多月了,对里面的一些基本的结构还算是有所了解。但是在做裸机程序来控制TFT屏时遇到了很多的麻烦,从最开始的一无所知到现在能够将图像和文字还有字符显示到上面,是经历了一个痛苦又漫长的过程,下面我来分享一下我的经验。

二、       2440LCD控制器内部结构和一些基本的概念

2440LCD控制器可以产生LCD所需要的控制信号,来完成对STN及TFT的控制。在对2440的LCD控制器操作之前必须要对一些概念和TFT的时序有所了解,然后才能深入的了解寄存器配置是一个怎么回事。

1、2440LCD控制器内部结构图

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

2、基本概念

a、LCD都是以点来显示的,将不同的点显示不同的颜色出来就是一幅图像;

b、行(line):显示器的指针从LCD的最左侧的点开始到最右侧显示点结;

c、帧(fram):从最顶端的行开始到最底端的行为一帧,也即一幅的图像为一帧;

d、HSYNC/VLINE/CPV:显示一行数据时间频率水平同步信号(TFT)/行同步脉冲信号(STN)/SEC TFT信号;

e、VSYNC/VFRAME/STV:显示一帧数据所需要的时间垂直同步信号(TFT)/帧同步信号(STN)/SEC TFT信号;

 

三、       常见的TFT屏的时序分析

图1  TFT时序分析

VSYNC与HSYNC前面已经定义过了。

VCLK:LCD指针移动一个点的时间频率,也称像素移动频率

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信号

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;

四、       2440LCD程序分析

2440LCD有5个控制寄存器:LCDCON1/2/3/4/5,3个Vedio data寄存器:LCDSADDR1/2/3等寄存器。

1、  单个像点的显示函数

void PutPixel(U32 x,U32 y, U32 c )

{

       if ( (x < SCR_XSIZE_TFT) && (y < SCR_YSIZE_TFT) )

              LCD_BUFFER[(y)][(x)] = c;

}

2、  初始化寄存器的配置函数

void Lcd_Init(void)

{

       rGPCUP  = 0x00000000;

       rGPCCON = 0xaaaa02a9;//GPC567为输入,GPC0为输出

        

       rGPDUP  = 0x00000000;

       rGPDCON=0xaaaaaaaa; //Initialize VD[15:8]  LCD的数据口

 

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

           // TFT LCD panel,16bpp TFT,ENVID=off,设置了VCLK的值

       rLCDCON2=(VBPD<<24)|(LINEVAL_TFT<<14)|(VFPD<<6)|(VSPW);

       rLCDCON3=(HBPD<<19)|(HOZVAL_TFT<<8)|(HFPD);

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

       rLCDCON5 = (1<<11) | (0<<10) | (1<<9) | (1<<8) | (0<<7) | (0<<6) | (1<<3)  |(BSWP<<1) | (HWSWP);//输出为5:6:5格式

       //10位表示VD数据在SCLK下降沿时被提取  8、9位表示VSYNC与HSYNC脉冲为负极性 7数据脉冲极性正常

       //6位数据全能脉冲极性正常 3位全能LCD_POWER

       rLCDSADDR1=(((U32)LCD_BUFFER>>22)<<21)|M5D((U32)LCD_BUFFER>>1);//系统内存地址A[30:22]处的Bank位置为图像缓冲

rLCDSADDR2=M5D( ((U32)LCD_BUFFER+(SCR_XSIZE_TFT*LCD_YSIZE_TFT*2))>>1 );//SCR_XSIZE_TFT*LCD_YSIZE_TFT*2 即先右移一位

                                                                                                                                     //取低21位

       rLCDSADDR3=(((SCR_XSIZE_TFT-LCD_XSIZE_TFT)/1)<<11)|(LCD_XSIZE_TFT/1);//offsize的值为0

       rLCDINTMSK|=(3); // MASK LCD Sub Interrupt

       rTCONSEL &= (~7) ;     // Disable LPC3480

       rTPAL=0; // Disable Temp Palette 暂存的调色寄存器

}

可以参照上面对一一些参数的定义解释来看些程序,同时也要结合LCD控制寄存器来对程序进行分析。

五、       TFT显示图像和字符

1、         TFT图像显示

/**************************************************************

在LCD屏幕上指定坐标点画一个指定大小的图片

**************************************************************/

void Paint_Bmp(int x0,int y0,int h,int l,unsigned char bmp[])

{

       int x,y;

       U32 c;

       int p = 0;

      

    for( y = y0 ; y < l ; y++ )

    {

           for( x = x0 ; x < h ; x++ )

           {

                  c = bmp[p+1] | (bmp[p]<<8) ;//采用的16位显示 格式 5:5:5:1

 

                     if ( ( (x0+x) < SCR_XSIZE_TFT) && ( (y0+y) < SCR_YSIZE_TFT) )

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

                    

                  p = p + 2 ;

           }

    }

}

 

2、         字符的显示

每一个字符要占用8*16个点。因为我采用的是3.5TFT屏没有字库,所有要编写一个ASCII码的库函数:font.c

 

/**************************************************************

在LCD屏幕上指定坐标点写ASCII码

参数1:X的坐标

参数2:Y的坐标

参数3:显示的字符输入ASCII码

参数4:文字颜色

参数5:背景色

参数6:是否显示设定的背景色

**************************************************************/

void Lcd_PutASCII(unsigned int x,unsigned int y,unsigned char ch,unsigned int c,unsigned int bk_c,unsigned int st)

{

       unsigned short int i,j;

       unsigned char *pZK,mask,buf;

      

      

 

       pZK = &__VGA[ch*16];//VGA为ASCII码的库,每一个字符对应16个数,每个数有8位

                                            //字符显示原理是8*16个点,行8个点,列16个点

       for( i = 0 ; i < 16 ; i++ )

       {

              mask = 0x80;

              buf = pZK[i];

              for( j = 0 ; j < 8 ; j++ )

              {

                     if( buf & mask )  //对于buf中的某一位若为1,则在显示屏上对应的点要打开

                     {

                            PutPixel(x+j,y+i,c);

                     }

                     else        //否则对应的点就显示底色

                     {

                            if( !st )

                            {

                                   PutPixel(x+j,y+i,bk_c);

                            }

                     }

           

                     mask = mask >> 1; //对应其余位

              }

       }

}

原创粉丝点击