TQ2440之LCD

16×16点阵字库中, 字符的信息结构采用以行排列的形式, 共有16行, 每行有16点, 分别存放在两个字节内. 因此, 每个字符共占用32个字节. 字节的存放顺序为从左到右, 从上到下。

24×24点阵字库中, 字符的信息结构采用以列排列的形式, 共有24列, 每列有24点, 分别存放在三个字节内. 因此, 每个字符共占用72个字节. 字节的存放顺序为从上到下, 从左到右。

点阵结构不同, 对应的字符编码方案也不完全相同。

16×16点阵字库中, 每个字符占32个字节, 每94个字符为一区, 共87个区. 其中1~15区为常用符号区(包括数字0~9及大小写英文字母), 16~86区为常用汉字, 其排列是以汉语拼音为序, 从一声到四声, 即从“啊(a)”排到“柞zuo”, 第87区为生僻汉字。
24×24点阵字库中, 每个字符占72个字节, 取消了常用符号区, 1~71区为常用汉字区, 其它方面与16×16点阵汉字相同。

汉字在16*16点阵字库中的起始位置计算公式:P= (S1- 161)×94+ (S2- 161)×32+ 1.

 为了保证系统的中西文兼容,意味着系统的机内码中必须保持ASCII(IBM-PC采用该码作为西文字符的机内码)的使用,同时又要允许汉字机内码的使用,并且使两者之间没有冲突。如果用GB2312-80中的国标码作为机内码,则在系统中同时存在ASCII码和国标码时,将会产生二义性。例如,机内有两个字节的内容分别为30H和21H,它们既可以表示汉字“啊”的国标码,又可以表示字符“0”和“!”的ASCII码。所以,原原本本地采用国标码作为汉字机内码是不行的,必须要加以适当的变换。
  一般情况下是将国标码的每个字节的高位置成1,作为汉字机内码,这种编码称作为变形国标码。这样作既解决了西文机内码与汉字机内码的二义性,又保证汉字机内码与国标码之间有极简单的对应关系。

TFT LCD时序图:

外部引脚信号:
VSYNC: 垂直同步信号,表示扫描1帧的开始。
HSYNC: 水平同步信号,表示扫描1行的开始。
VDEN:数据使能信号。
VD[23:0] : LCD像素数据输出端口。
VCLK:像素时钟信号。
寄存器参数:
VSPW:垂直同步信号的脉宽,单位为1行(Line)的时间。
VFPD: 垂直同步信号的前肩,单位为1行(Line)的时间。
VBPD: 垂直同步信号的后肩,单位为1行(Line)的时间。
LINEVAL :垂直显示尺寸-1,即屏行宽-1。
HBPD:水平同步信号的后肩,单位为1VCLK的时间。
HFPD:水平同步信号的前肩,单位为1VCLK的时间。
HSPW:水平同步信号的脉宽,单位为1VCLK的时间。
HOZVAL:水平显示尺寸-1,即屏列宽-1。

由上图可知:
扫描一帧所需的时间:
T1 = ((VSPW+1)+(VBPD+1)+( LINEVAL+1)+(VFPD+1))个行时间。
扫描一行所所需的时间:
T2= ((HSPW+1)+(HSPD+1)+(HFPD+1)+ (HOZVAL+1))个VCLK时间。
而一个VCLK时间由LCD寄存器LCDCON1内的CLKVAL决定:
T3=HCLK/[2*(CLKVAL+1)]
因此扫描一帧所需的时间:
T=[(VSPW+1)+(VBPD+1)+( LINEVAL+1)+(VFPD+1)]* [(HSPW+1)+(HSPD+1)+(HFPD+1)+ (HOZVAL+1)]* HCLK/[2*(CLKVAL+1)]
即帧频率为:1/T。

TQ2440配套的TFT LCD不是三星的,而是东华的,东华手册图如下:

注意:三星手册上的LCD时序图和板子上的东华屏幕的时序图有不同的地方,从东华的手册上可以看出VSPW、VBPD、VFPD等和HSPW、HBPD、HFPD以及VCKL的关系。三星手册的时序图是对三星LCD来说的,东华的时序图和三星的是不一样的,数据手册上显示两者的极性相反。因此设置HSYNC、VSYNC的极性反转。

液晶初始化:

static void Lcd_Init(void)
{
       rGPCUP  = 0x00000000;
       rGPCCON = 0xaaaa02a9; 

//    rGPDUP=0xffffffff; // Disable Pull-up register
       rGPDUP  = 0x00000000;
       rGPDCON=0xaaaaaaaa; //Initialize VD[15:8]

       rLCDCON1=(CLKVAL_TFT << 8)|(MVAL_USED << 7)|(3 <<5 )|(12 << 1)|0;
        // TFT LCD panel,16bpp TFT,ENVID=off
       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 VCLK posedge BSWP=0,HWSWP=1;

       rLCDSADDR1=( ((U32)LCD_BUFFER>>22)<<21) | M5D( (U32)LCD_BUFFER>>1 );
       rLCDSADDR2=M5D( ((U32)LCD_BUFFER+(SCR_XSIZE_TFT * LCD_YSIZE_TFT * 2)) >> 1 );
       rLCDSADDR3=(((SCR_XSIZE_TFT - LCD_XSIZE_TFT) / 1) << 11)|(LCD_XSIZE_TFT / 1);
       rLCDINTMSK|=(3); // MASK LCD Sub Interrupt
       rTCONSEL &= (~7) ;     // Disable LPC3480
       rTPAL=0; // Disable Temp Palette
}
LCD电源控制:
static
void Lcd_PowerEnable(int invpwren,int pwren) { //GPG4 is setted as LCD_PWREN rGPGUP = rGPGUP & ( ~(1 << 4)) |(1 << 4); // Pull-up disable rGPGCON = rGPGCON & ( ~(3 << 8)) |(3 << 8); //GPG4=LCD_PWREN rGPGDAT = rGPGDAT | (1 << 4) ; // invpwren=pwren; //Enable LCD POWER ENABLE Function rLCDCON5 = rLCDCON5 & ( ~(1 << 3)) |(pwren << 3); // PWREN rLCDCON5 = rLCDCON5 & ( ~(1 << 5)) |(invpwren << 5); // INVPWREN }
显示图片:
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) ; if ( ( (x0+x) < SCR_XSIZE_TFT) && ( (y0+y) < SCR_YSIZE_TFT) ) LCD_BUFFER[y0+y][x0+x] = c ; p = p + 2 ; } } }
显示一个格式化的字符串:
void
Lcd_printf(unsigned int x,unsigned int y,unsigned int c,unsigned int bk_c,unsigned int st,char *fmt,...) { char __LCD_Printf_Buf[256]; va_list ap; unsigned char *pStr = (unsigned char *)__LCD_Printf_Buf; unsigned int i = 0; va_start(ap,fmt); vsprintf(__LCD_Printf_Buf,fmt,ap); va_end(ap); while(*pStr != 0 ) { switch(*pStr) { case '\n' : break; default: { if( *pStr > 0xA0 & *(pStr+1) > 0xA0 ) //中文输出 { Lcd_PutHZ( x , y , (*pStr - 0xA0)*0x0100 + *(pStr+1) - 0xA0 , c , bk_c , st); pStr++; i++; x += 16; } else //英文输出 { Lcd_PutASCII(x , y , *pStr , c , bk_c , st); x += 8; } break; } } pStr++; i++; if(i > 256) break; } }
显示汉子:
void
Lcd_PutHZ(unsigned int x,unsigned int y,unsigned short int QW,unsigned int c,unsigned int bk_c,unsigned int st) { unsigned short int i,j; unsigned char *pZK,mask,buf; pZK = &__CHS[ ( ( (QW >> 8) - 1 )*94 + (QW & 0x00FF)- 1 )*32 ]; for( i = 0 ; i < 16 ; i++ ) { // mask = 0x80; buf = pZK[i*2]; for( j = 0 ; j < 8 ; j++ ) { if( buf & mask ) { PutPixel(x+j,y+i,c); } else { if( !st ) { PutPixel(x+j,y+i,bk_c); } } mask = mask >> 1; } // mask = 0x80; buf = pZK[i*2 + 1]; for( j = 0 ; j < 8 ; j++ ) { if( buf & mask ) { PutPixel(x+j + 8,y+i,c); } else { if( !st ) { PutPixel(x+j + 8,y+i,bk_c); } } mask = mask >> 1; } } }
显示ASCII码:
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]; for(i = 0 ; i < 16 ; i++) { mask = 0x80; buf = pZK[i]; for(j = 0 ; j < 8 ; j++) { if(buf & mask) { PutPixel(x+j,y+i,c); } else { if(!st) { PutPixel(x+j,y+i,bk_c); } } mask = mask >> 1; } } }

 

posted @ 2013-08-08 23:14  zpehome  阅读(559)  评论(0编辑  收藏  举报