哈尔滨理工大学软件工程专业08-7李万鹏原创作品,转载请标明出处
http://blog.csdn.net/woshixingaaa/archive/2010/12/16/6080850.aspx
首先了解TFT LCD的时序,每个VSYNC信号表示一帧数据的开始,每个HSYNC表示一行数据的开始,无论这些数据是否有效,每个VCLK表示正在传输一个像素的数据,无论它是否有效。VSPW称为垂直同步信号的脉宽,VBPD称为垂直同步信号的后肩,VFPD称为垂直同步信号的前肩。HSPW称为水平同步信号的脉宽,HBPD称为水平同步信号的后肩,HFPD称为水平同步信号的前肩。查看时序图,VSYNC信号有效时,表示一帧数据的开始,VSPW表示VSYNC信号的脉冲宽度为(VSPW+1)个HSYNC信号周期,即(VSYNC+1)行,这(VSPW+1)行的数据无效。VSYNC信号脉冲之后,还要经过(VBPD+1)个HSYNC信号周期,有效的行数据才出现。所以,在VSYNC信号之后,总共还要经过(VSPW+1+VBPD+1)个无效行,第一个有效的行才会出现。随后即发出(LINEVAL+1)行的有效数据,随后是(VFPD+1)个无效行。HSYNC的类似。不过是以VCLK信号周期为单位。然后主要就是配置5个LCD控制寄存器,3个帧缓冲区起始地址寄存器。注意HSYNC和VSYNC信号,CPU发出的是正脉冲,LCD需要的是负的,所以极性取反,INVVLINE和INVVFRAME置1。M5D宏是用来取低21位。有一些右移一位的操作,主要是进行字节和半字地址的转换。LCD中需要的半字地址,帧缓冲区最低位是A[1]。BSWP和HWSWP是字节和半字交换,主要是处理大小端问题,如果输出的汉字反了,置这个位为1。volatile U32 LCD_BUFFER[240][320];这个是设的帧缓冲区,即视口,是帧内存的一部分,这个程序中,帧内存和帧缓冲区一样大。帧内存在SDRAM中,相当于显存。只要向帧缓冲区中写入数据,LCD的DMA控制器会自动将数据从总线发到LCD驱动器。在VCLK的上升沿发送数据,在VCLK的下降沿,LCD驱动器接受数据。BPP24BL是设置LCD的显示模式为24BPP时,一个4字节中哪3个字节有效。PAGESIZE是帧缓冲区的水平宽度,OFFSET是一行剩下的长度。VD[23]~VD[0],是24根数据线,即RGB信号线。
下面的程序将LCD涂成红色,然后画一个蓝色的矩形。
#define rGPCCON (*(volatile unsigned *)0x56000020) #define rGPCUP (*(volatile unsigned *)0x56000028) #define rGPDCON (*(volatile unsigned *)0x56000030) #define rGPDUP (*(volatile unsigned *)0x56000038) #define rLCDCON1 (*(volatile unsigned *)0x4d000000) #define rLCDCON2 (*(volatile unsigned *)0x4d000004) #define rLCDCON3 (*(volatile unsigned *)0x4d000008) #define rLCDCON4 (*(volatile unsigned *)0x4d00000c) #define rLCDCON5 (*(volatile unsigned *)0x4d000010) #define rLCDSADDR1 (*(volatile unsigned *)0x4d000014) #define rLCDSADDR2 (*(volatile unsigned *)0x4d000018) #define rLCDSADDR3 (*(volatile unsigned *)0x4d00001c) #define rLCDINTMSK (*(volatile unsigned *)0x4d00005c) #define rTPAL (*(volatile unsigned *)0x4d000050) #define rGPGCON (*(volatile unsigned *)0x56000060) //Port G control #define rGPGDAT (*(volatile unsigned *)0x56000064) //Port G data #define rGPGUP (*(volatile unsigned *)0x56000068) //Pull-up control G #define rLCDINTMSK (*(volatile unsigned *)0x4d00005c) #define rTPAL (*(volatile unsigned *)0x4d000050) #define rTCONSEL (*(volatile unsigned *)0x4d000060) //LPC3600 Control --- edited by junon //垂直同步信号的脉宽、后肩和前肩 #define VSPW 15 #define VBPD 3 #define VFPD 5 //水平同步信号的脉宽、后肩和前肩 #define HSPW 8 #define HBPD 58 #define HFPD 15 #define CLKVAL 10 #define HOZVAL 319 #define LINEVAL 239 #define PWREN 1 #define MMODE 0 #define PNRMODE 3 #define BPPMODE 13 #define INVVCLK 0 #define INVVD 0 #define INVVDEN 0 #define U32 unsigned int #define M5D(n) ((n) & 0x1fffff) #define PAGEWIDTH 320 #define OFFSIZE 0 #define LCD_XSIZE 320 #define LCD_YSIZE 240 #define SCR_XSIZE 320 #define SCR_YSIZE 240 #define INVVLINE 1 #define INVVFRAME 1 #define BPP24BL 0 #define BSWP 0 #define HWSWP 0 volatile U32 LCD_BUFFER[240][320]; void Init_LCD(){ rLCDCON1=(CLKVAL<<8)|(MMODE<<7)|(PNRMODE<<5)|(BPPMODE<<1)|0; //设置CLKVAL,VCLK=HCLK/[(CLKVAL+1)*2],决定VM的触发方式,选择显示模式和BPP模式,暂时不要开启LCD,因为还没有设置好 rLCDCON2=(VBPD<<24)|(LINEVAL<<14)|(VFPD<<6)|(VSPW); //rLCDCON2,rLCDCON3和rLCDCON4主要设置时序 rLCDCON3=(HBPD<<19)|(HOZVAL<<8)|(HFPD); rLCDCON4=(HSPW); rLCDCON5 = (BPP24BL<<12) | (INVVCLK<<10) | (INVVLINE<<9) | (INVVFRAME<<8) | (0<<7) | (INVVDEN<<6) | (PWREN<<3) |(BSWP<<1) | (HWSWP); //INVVLINE和INVVFRAME需要进行翻转,因为CPU发出的是正脉冲,LCD使用的是负脉冲,所以要改变极性,PWREN使能电源信号 rLCDSADDR1=(((U32)LCD_BUFFER>>22)<<21)|M5D((U32)LCD_BUFFER>>1); rLCDSADDR2=M5D(((U32)LCD_BUFFER+(SCR_XSIZE*SCR_YSIZE*4))>>1 ); rLCDSADDR3=PAGEWIDTH*32/16; rLCDINTMSK|=(3); rTCONSEL = 0; rGPCUP = 0x0; rGPDCON = 0xaaaaaaaa; rGPCCON = 0xaaaa02a9; rGPDUP = 0x0; rGPGUP=rGPGUP&(~(1<<4))|(1<<4); rGPGCON=rGPGCON&(~(3<<8))|(3<<8); rLCDCON1 |= 1; //使能数据输出和LCD控制信号 } void Paint_background(U32 c){ unsigned int i, j; for(j = 0; j < LCD_YSIZE; j++) for(i = 0; i < LCD_XSIZE; i++) LCD_BUFFER[j][i] = c; } void Paint_rectangle(U32 c){ int i, j; for(i = 100; i < 200; i++) for(j = 100; j < 200; j++) LCD_BUFFER[i][j] = c; } int LcdMain(){ Init_LCD(); Paint_background(0xCD5C5C); Paint_rectangle(0x000080); while(1); }
LightPink | 浅粉色 | #FFB6C1 | 255,182,193 |
Pink | 粉红 | #FFC0CB | 255,192,203 |
Crimson | 猩红 | #DC143C | 220,20,60 |
LavenderBlush | 脸红的淡紫色 | #FFF0F5 | 255,240,245 |
PaleVioletRed | 苍白的紫罗兰红色 | #DB7093 | 219,112,147 |
HotPink | 热情的粉红 | #FF69B4 | 255,105,180 |
DeepPink | 深粉色 | #FF1493 | 255,20,147 |
MediumVioletRed | 适中的紫罗兰红色 | #C71585 | 199,21,133 |
Orchid | 兰花的紫色 | #DA70D6 | 218,112,214 |
Thistle | 蓟 | #D8BFD8 | 216,191,216 |
plum | 李子 | #DDA0DD | 221,160,221 |
Violet | 紫罗兰 | #EE82EE | 238,130,238 |
Magenta | 洋红 | #FF00FF | 255,0,255 |
Fuchsia | 灯笼海棠(紫红色) | #FF00FF | 255,0,255 |
DarkMagenta | 深洋红色 | #8B008B | 139,0,139 |
Purple | 紫色 | #800080 | 128,0,128 |
MediumOrchid | 适中的兰花紫 | #BA55D3 | 186,85,211 |
DarkVoilet | 深紫罗兰色 | #9400D3 | 148,0,211 |
DarkOrchid | 深兰花紫 | #9932CC | 153,50,204 |
Indigo | 靛青 | #4B0082 | 75,0,130 |
BlueViolet | 深紫罗兰的蓝色 | #8A2BE2 | 138,43,226 |
MediumPurple | 适中的紫色 | #9370DB | 147,112,219 |
MediumSlateBlue | 适中的板岩暗蓝灰色 | #7B68EE | 123,104,238 |
SlateBlue | 板岩暗蓝灰色 | #6A5ACD | 106,90,205 |
DarkSlateBlue | 深岩暗蓝灰色 | #483D8B | 72,61,139 |
Lavender | 薰衣草花的淡紫色 | #E6E6FA | 230,230,250 |
GhostWhite | 幽灵的白色 | #F8F8FF | 248,248,255 |
%3 |