`
nathan09
  • 浏览: 144195 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

s3c2410+LCD+TFT+驱动+图片显示

 
阅读更多

最近研究了s3c2410下LCD控制器的相关知识,主要的参考资料就是三星s3c2410数据手册(arm920T),英文版,看的不是非常明白,后来参考了WinCE下的部分代码,似有所领悟。于是写了此程序,用以在LCD上显示图片。

本程序可以在LCD上居中显示小于800×480的任意大小的图片。用到的辅助工具就是上篇文章中的RGB分量提取器.

关键模块如下:

0.全局变量的定义:

#defineDMA_BUFFER_BASE0xAC000000
#defineDMA_PHYSICAL_BASE0x35000000//S3C2410X010x30000000

#defineFRAMEBUF_BASE(DMA_BUFFER_BASE+0x00100000)
#defineFRAMEBUF_DMA_BASE(DMA_PHYSICAL_BASE+0x00000000)//0x00100000

#defineIOP_BASE0x56000000//0x56000000

typedef
struct...{
unsigned
intGPACON;//00
unsignedintGPADAT;
unsigned
intPAD1[2];
...................
}
IOPreg;

//DefineLCDtypeofS3C2400X01
#defineTFT24BPP3
#defineLCDTYPETFT24BPP//defineLCDtypeasupperdefinition.
//
//Registers:LCDController
//

#defineLCD_BASE0x4D000000//0x4D000000
typedef
struct...{
unsigned
intLCDCON1;//00
unsignedintLCDCON2;//04
unsignedintLCDCON3;//08
.....................
}
LCDreg;

//LCDregistervalue...

#defineMODE_TFT_24BIT(224)
#defineLCD_XSIZE_TFT(800)
#defineLCD_YSIZE_TFT(480)
#defineARRAY_SIZE_TFT_24BIT(SCR_XSIZE*4*SCR_YSIZE)
#defineHOZVAL_TFT(LCD_XSIZE_TFT-1)
#defineLINEVAL_TFT(LCD_YSIZE_TFT-1)
#defineMVAL(13)
#defineMVAL_USED(0)
#defineVBPD((32-1)&0xff)
#defineVFPD((11-1)&0xff)
#defineVSPW((2-1)&0x3f)
#defineHBPD((88-1)&0x7f)
#defineHFPD((40-1)&0xff)
#defineHSPW((128-1)&0xff)
#defineCLKVAL_TFT(1)
#defineM5D(n)((n)&0x1fffff)

U32
*pLCDBuffer24=(U32*)FRAMEBUF_DMA_BASE;
U32
*picData;

volatileLCDreg*s2410LCD=(LCDreg*)LCD_BASE;

volatileIOPreg*s2410IOP=(IOPreg*)IOP_BASE;

intnCol=800;//象素列数
intnRow=480;//象素行数
U32*picDataT=NULL;

1.入口函数,其中包括了相应端口、寄存器初始化的入口,aa,bb,cc,dd,ee是可选择的5幅预定义图片的GRB码数组,具体代码如下

voidlcd_Main(void)
...{
charsel;
Uart_Printf(
"Lcd_Driver ");

lcd_port_init();
lcd_regs_init();

Uart_Printf(
"selectonePicturetoshow(123450) ");

while((sel=Uart_Getch())!='e')
...{
Uart_Printf(
"%c ",sel);
switch(sel)
...{
case'1':
picData
=(U32*)aa;break;
case'2':
picData
=(U32*)bb;break;
case'3':
picData
=(U32*)cc;break;
case'4':
picData
=(U32*)dd;break;
case'5':
picData
=(U32*)ee;break;
default:
Uart_Printf(
"Input123450 ");
}


lcd_display();

Uart_Printf(
"selectonePicturetoshow(123450) ");
}

Uart_Printf(
"Exit");
//lcd_close();
}

2。相应端口设置,包括GPC,GPD,GPG的相应位的设置:

voidlcd_port_init(void)
...{

//LCDportinitialize.
s2410IOP->GPCUP=0xFFFFFFFF;
s2410IOP
->GPCCON=0xAAAAAAAA;


s2410IOP
->GPDUP=0xFFFFFFFF;
s2410IOP
->GPDCON=0xAAAAAAAA;

s2410IOP
->GPGCON&=~(3<<8);/**//*SetLCD_PWRENasoutput*/
s2410IOP
->GPGCON|=(1<<8);

s2410IOP
->GPGDAT|=(1<<4);//*BacklightON,关键,不然lcd不亮
}

3。控制寄存器设置:

voidlcd_regs_init(void)
...{

#ifdefMODE_TFT_24BIT

s2410LCD
->LCDCON1=(1<<8)|//*VCLK=HCLK/((CLKVAL+1)*2)->About7Mhz
(MVAL_USED<<7)|//*0:EachFrame
(3<<5)|//TFTLCDPannel
(13<<1)|//Y://24bppMode
(0<<0);//DisableLCDOutput

s2410LCD
->LCDCON2=(VBPD<<24)|//*VBPD:((32-1)&0xff)
(LINEVAL_TFT<<14)|//*LINEVAL_TFT:480-1
(VFPD<<6)|//*VFPD:((11-1)&0xff)
(VSPW<<0);//*VSPW:((2-1)&0x3f)

s2410LCD
->LCDCON3=(HBPD<<19)|//*HBPD:((88-1)&0x7f)
(HOZVAL_TFT<<8)|//*HOZVAL_TFT:800-1
(HFPD<<0);//*HFPD:((40-1)&0xff)


s2410LCD
->LCDCON4=(MVAL<<8)|//*MVAL:13
(HSPW<<0);//*HSPW:((128-1)&0xff)

s2410LCD
->LCDCON5=0x00000000;
/**//*
s2410LCD->LCDCON5=(0<<12)|//BPP24BL:LSBvalid
(0<<11)|//FRM565MODE:5:5:5:1Format
(0<<10)|//INVVCLK:VCLKFallingEdge
(0<<9)|//INVVLINE:InvertedPolarity
(0<<8)|//INVVFRAME:InvertedPolarity
(0<<7)|//INVVD:Normal
(0<<6)|//INVVDEN:Normal
(0<<5)|//INVPWREN:Normal
(0<<4)|//INVENDLINE:Normal
(0<<3)|//PWREN:DisablePWREN
(0<<2)|//ENLEND:DisableLENDsignal
(0<<1)|//BSWP:SwapDisable
(0<<0);//HWSWP:SwapEnable
*/

s2410LCD
->LCDSADDR1=((FRAMEBUF_DMA_BASE>>22)<<21)|
((M5D(FRAMEBUF_DMA_BASE
>>1))<<0);
//LCDBANK=((FRAMEBUF_DMA_BASE>>22)<<21)
//LCDBASEU=((M5D(FRAMEBUF_DMA_BASE)>>1)<<0)

s2410LCD
->LCDSADDR2=(M5D(FRAMEBUF_DMA_BASE)>>1)+((LCD_XSIZE_TFT*2)+0)*(LINEVAL_TFT+1);
//LCDBASEL=s2410LCD->LCDSADDR2

s2410LCD
->LCDSADDR3=(((LCD_XSIZE_TFT-LCD_XSIZE_TFT)/1)<<11)|(LCD_XSIZE_TFT);
//OFFSIZE=(((LCD_XSIZE_TFT-LCD_XSIZE_TFT)/1)<<11)==0
//PAGEWIDTH=(LCD_XSIZE_TFT)

s2410LCD
->TPAL=0x0;
s2410LCD
->LCDCON1|=1;

#endif
}

4。居中显示图片:


voidlcd_display(void)
...{
inty;
intpw,ph;
intsw=800,sh=480;
U32
*pdata;
U32
*pBt=NULL;

lcd_clear();

get_XY();//获得图片的宽与高,以保存在RGB数组的头两个字节。
pw
=nCol,ph=nRow;

pBt
=pLCDBuffer24+sw*(sh/2-ph/2)+(sw/2-pw/2);//定位图片显示的起始位置

pdata
=(U32*)picDataT;
for(y=0;y<nRow;++y)
...{
memcpy((pBt
+800*y),(char*)pdata,nCol*4);//一行一行显示
pdata
=(U32*)(pdata+nCol);
}


s2410LCD
->LCDCON1|=0;

}

5。每次显示都要获得图片的宽度和高度,并且清除前面的屏幕,所谓清屏就是显示背景图片(蓝色):


voidlcd_clear()
...{
inty=0;
U32
*pdata=(U32*)(bgData+2);
for(y=0;y<480;++y)
...{
memcpy((pLCDBuffer24
+800*y),(char*)pdata,800*4);
pdata
=(U32*)(pdata+800);
}

}


voidget_XY(void)
...{
nCol
=picData[0];
nRow
=picData[1];

picDataT
=(U32*)(picData+2);
}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics