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 = 319
HOZVAL: LCD笔直像素-1,如240-1 = 239
HFPD: 行开端前的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 * 2
OFFSIZE:虚拟屏幕左边偏移的字节数,假如不运用虚拟屏幕,设置为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)!
9、翻开视频输出
ENVID设为1 (LCDCON1:0写入1)
void Test_Lcd_Tft_8Bit_640480(void)
{
int i,j,k;
Lcd_Palette8Bit_Init();//调色板初始化,格局为 5:6:5 并赋值调色板的初始地址
void Lcd_Palette8Bit_Init(void)
{
int i;
U32 *palette;
rLCDCON5|=(1<<11); // 5:6:5 Palette Setting
palette=(U32 *)PALETTE;
for(i=0;i<256;i++)
*palette++=DEMO256pal[i];
}
Lcd_Port_Init(); //LCD端口引脚初始化,包含第二功用,数据线及操控信号线等设置, Disable Pull-up registe
static void Lcd_Port_Init(void)
{
save_rGPCCON=rGPCCON;
save_rGPCDAT=rGPCDAT;
save_rGPCUP=rGPCUP;
save_rGPDCON=rGPDCON;
save_rGPDDAT=rGPDDAT;
save_rGPDUP=rGPDUP;
rGPCUP=0xffffffff; // Disable Pull-up register
rGPCCON=0xaaaaaaaa; //Initialize VD[7:0],LCDVF[2:0], VM, VFRAME,
//VLINE, VCLK,LEND 初始化数据线与各操控信号
rGPDUP=0xffffffff; // Disable Pull-up register
rGPDCON=0xaaaaaaaa; //Initialize VD[23:8]
}
Lcd_Init(MODE_TFT_8BIT_640480);//针对各形式下对帧缓冲开始地址及各操控寄存器rLCDCONn等进行相应设置等进行设置
void Lcd_Init(int type)
{
switch(type)
{……
case MODE_TFT_1BIT_640480:
frameBuffer1BitTft640480=(U32 (*)[SCR_XSIZE_TFT_640480/32])LCDFRAMEBUFFER;
/*//界说一个行数组指针extern U32 (*frameBuffer1BitTft640480)[SCR_XSIZE_TFT_640480/32],每行包含320个U32单元指针LCDFRAMEBUFFER进行强制类型转化后赋给frameBuffer8BitTft240320,即frameBuffer8BitTft240320指向LCDFRAMEBUFFER*/
rLCDCON1=(CLKVAL_TFT_640480<<8)|(MVAL_USED<<7)|(3<<5)|(8<<1)|0;
/*//#define CLKVAL_TFT_640480 (1)
//53.5hz @90Mhz
//VSYNC,HSYNC should be inverted
//HBPD=47VCLK,HFPD=15VCLK,HSPW=95VCLK
//VBPD=32HSYNC,VFPD=9HSYNC,VSPW=1HSYNC
// TFT LCD panel,8bpp TFT,ENVID=off 显现形式为TFT, VM速率为每帧一次,bpp为8bpp,制止输出LCD视频数据及操控信号*/
rLCDCON2=(VBPD_640480<<24)|(LINEVAL_TFT_640480<<14)|(VFPD_640480<<6)|(VSPW_640480);
rLCDCON3=(HBPD_640480<<19)|(HOZVAL_TFT_640480<<8)|(HFPD_640480);
rLCDCON4=(MVAL<<8)|(HSPW_640480);
rLCDCON5=(1<<11)|(1<<9)|(1<<8);//FRM5:6:5,HSYNC and VSYNC are inverted
rLCDSADDR1=(((U32)frameBuffer1BitTft640480>>22)<<21)|M5D((U32)frameBuffer1BitTft640480>>1);
rLCDSADDR2=M5D( ((U32)frameBuffer1BitTft640480+(SCR_XSIZE_TFT_640480*LCD_YSIZE_TFT_640480/8))>>1 );
rLCDSADDR3=(((SCR_XSIZE_TFT_640480-LCD_XSIZE_TFT_640480)/16)<<11)|(LCD_XSIZE_TFT_640480/16);
rLCDINTMSK|=(3);// MASK LCD Sub Interrupt
rLPCSEL&=(~7);// Disable LPC3600
rTPAL=0;// Disable Temp Palette
break;
……..
}
}
Glib_Init(MODE_TFT_8BIT_640480);//设置各像素点bpp的格局
void Glib_Init(int type)
{
switch(type)
{
case MODE_STN_1BIT:
……………….
case MODE_TFT_8BIT_640480://#define MODE_TFT_8BIT_640480
PutPixel=_PutTft8Bit_640480;
break;
………………
}
void _PutTft8Bit_640480(U32 x,U32 y,U32 c)
{
if(x
frameBuffer8BitTft640480[(y)][(x)/4]=( frameBuffer8BitTft640480[(y)][x/4]
& ~(0xff000000>>((x)%4)*8) ) | ( (c&0x000000ff)<<((4-1-((x)%4))*8) );
}
/*
U32 (*frameBuffer8BitTft640480)[SCR_XSIZE_TFT_640480/4];//界说一行数组指针,具有SCR_XSIZE_TFT_640480/4=320个U32类型的元素
frameBuffer8BitTft640480=(U32 (*)[SCR_XSIZE_TFT_640480/4])LCDFRAMEBUFFER;//将LCDFRAMEBUFFER强制转化为数组指针类型后赋给frameBuffer8BitTft640480 //#define LCDFRAMEBUFFER 0x33800000
rLCDSADDR1=(((U32)frameBuffer8BitTft640480>>22)<<21)|M5D((U32)frameBuffer8BitTft640480>>1);rLCDSADDR2=M5D( ((U32)frameBuffer8BitTft640480+(SCR_XSIZE_TFT_640480*LCD_YSIZE_TFT_640480/1))>>1 );
frameBuffer8BitTft640480[(y)][(x)/4]=( frameBuffer8BitTft640480[(y)][x/4]
& ~(0xff000000>>((x)%4)*8) ) | ( (c&0x000000ff)<<((4-1-((x)%4))*8) );
//extern U32 (*frameBuffer8BitTft640480)[SCR_XSIZE_TFT_640480/4];共包含行单元为320的U32行数组指针
//因为一个像素只占8个BIT,故一个U32单元存放了四个像素,关于一个X,需求先找到其地点的字:X/4,然后找到它地点该字中的方位:(x)%4),将其清0后再赋上相应的色彩值即: & ~(0xff000000>>((x)%4)*8) ) | ( (c&0x000000ff)<<((4-1-((x)%4))*8) :BSWP = 0//字节不行交郁闷, HWSWP = 0半字不行交流(1:可交流);P1在[31:24],P1在[23;16]....
*/
Lcd_PowerEnable(0, 1);//关掉电源
void Lcd_PowerEnable(int invpwren,int pwren)
{
//GPG4 is setted as LCD_PWREN界说引脚为第四功用即LCD_PWREN
rGPGUP=rGPGUP&(~(1<<4))|(1<<4); // Pull-up disable
rGPGCON=rGPGCON&(~(3<<8))|(3<<8); //GPG4=LCD_PWREN
//Enable LCD POWER ENABLE Function
rLCDCON5=rLCDCON5&(~(1<<3))|(pwren<<3); // PWREN
rLCDCON5=rLCDCON5&(~(1<<5))|(invpwren<<5); // INVPWREN
}
Lcd_EnvidOnOff(1);//答应LCD视频数据及LCD操控信号
void Lcd_EnvidOnOff(int on
{
if(on
rLCDCON1|=1; // ENVID=ON
else
rLCDCON1 =rLCDCON1 & 0x3fffe; // ENVID Off
}
Uart_Printf(“[TFT 256 COLOR(8bit/1pixel) LCD TEST] “);
Glib_ClearScr(0, MODE_TFT_8BIT_640480);//铲除屏幕
void Glib_ClearScr(U32 c, int type)
{
//Very inefficient function.
int i,j;
//if((type==MODE_TFT_1BIT_800600)|(type==MODE_TFT_8BIT_800600) |//(type==MODE_TFT_16BIT_800600))
if((type&0x4000)&&(type&0x400))
for(j=0;j
for(i=0;i
PutPixel(i,j,c);
//else if((type==MODE_TFT_1BIT_640480)|(type==MODE_TFT_8BIT_640480)|(type==MODE_TFT_16BIT_640480))
else if((type&0x4000)&&(type&0x200))
for(j=0;j
for(i=0;i
PutPixel(i,j,c); //在前面函数指针已赋值PutPixel=_PutTft8Bit_640480
…………
}
rTPAL = (1<<24)|((0xff)<<0); // Enable Temporary Palette : Blue
Uart_Printf(“TFT 256 color mode test 1. Press any key! “);
Uart_Getch();
k=0;
for(i=0;i<640;i+=40)
for(j=0;j<480;j+=30)
{
Glib_FilledRectangle(i,j,i+39,j+29,(k%256));
k++;
}
rTPAL = 0;
Uart_Printf(“TFT 256 color mode test 2. Press any key! “);
Uart_Getch();
……
}
frameBuffer8BitTft640480=(U32 (*)[SCR_XSIZE_TFT_640480/4])LCDFRAMEBUFFER;//将LCDFRAMEBUFFER强制转化为数组指针类型后赋给frameBuffer8BitTft640480 //#define LCDFRAMEBUFFER 0x33800000
rLCDSADDR1=(((U32)frameBuffer8BitTft640480>>22)<<21)|M5D((U32)frameBuffer8BitTft640480>>1);rLCDSADDR2=M5D( ((U32)frameBuffer8BitTft640480+(SCR_XSIZE_TFT_640480*LCD_YSIZE_TFT_640480/1))>>1 );
frameBuffer8BitTft640480[(y)][(x)/4]=( frameBuffer8BitTft640480[(y)][x/4]
& ~(0xff000000>>((x)%4)*8) ) | ( (c&0x000000ff)<<((4-1-((x)%4))*8) );
*/
Lcd_PowerEnable(0, 1);//关掉电源
void Lcd_PowerEnable(int invpwren,int pwren)
{
//GPG4 is setted as LCD_PWREN界说引脚为第四功用即LCD_PWREN
rGPGUP=rGPGUP&(~(1<<4))|(1<<4); // Pull-up disable
rGPGCON=rGPGCON&(~(3<<8))|(3<<8); //GPG4=LCD_PWREN
//Enable LCD POWER ENABLE Function
rLCDCON5=rLCDCON5&(~(1<<3))|(pwren<<3); // PWREN
rLCDCON5=rLCDCON5&(~(1<<5))|(invpwren<<5); // INVPWREN
}
Lcd_EnvidOnOff(1);//答应LCD视频数据及LCD操控信号
void Lcd_EnvidOnOff(int on
{
if(on
rLCDCON1|=1; // ENVID=ON
else
rLCDCON1 =rLCDCON1 & 0x3fffe; // ENVID Off
}
Uart_Printf(“[TFT 256 COLOR(8bit/1pixel) LCD TEST] “);
Glib_ClearScr(0, MODE_TFT_8BIT_640480);//铲除屏幕
void Glib_ClearScr(U32 c, int type)
{
//Very inefficient function.
int i,j;
//if((type==MODE_TFT_1BIT_800600)|(type==MODE_TFT_8BIT_800600) |//(type==MODE_TFT_16BIT_800600))
if((type&0x4000)&&(type&0x400))
for(j=0;j
for(i=0;i
PutPixel(i,j,c);
//else if((type==MODE_TFT_1BIT_640480)|(type==MODE_TFT_8BIT_640480)|(type==MODE_TFT_16BIT_640480))
else if((type&0x4000)&&(type&0x200))
for(j=0;j
for(i=0;i
PutPixel(i,j,c); //在前面函数指针已赋值PutPixel=_PutTft8Bit_640480
…………
}
rTPAL = (1<<24)|((0xff)<<0); // Enable Temporary Palette : Blue
Uart_Printf(“TFT 256 color mode test 1. Press any key! “);
Uart_Getch();
k=0;
for(i=0;i<640;i+=40)
for(j=0;j<480;j+=30)
{
Glib_FilledRectangle(i,j,i+39,j+29,(k%256));
k++;
}
rTPAL = 0;
Uart_Printf(“TFT 256 color mode test 2. Press any key! “);
Uart_Getch();
……
}