s3c2410 LCD图片显示
2012-06-02
标签: S3C2410

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

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

关键模块如下:

0、全局变量的定义:

#define DMA_BUFFER_BASE0xAC000000

#define DMA_PHYSICAL_BASE0x35000000// S3C2410X01 0x30000000

#define FRAMEBUF_BASE(DMA_BUFFER_BASE + 0x00100000)

#define FRAMEBUF_DMA_BASE(DMA_PHYSICAL_BASE + 0x00000000)//0x00100000

#define IOP_BASE0x56000000 // 0x56000000

typedef struct{

unsigned intGPACON;// 00

unsigned intGPADAT;

unsigned intPAD1[2];

...................

}IOPreg;

// Define LCD type of S3C2400X01

#define TFT24BPP3

#define LCDTYPETFT24BPP// define LCD type as upper definition.

//

// Registers : LCD Controller

//

#define LCD_BASE0x4D000000 // 0x4D000000

typedef struct{

unsigned intLCDCON1;// 00

unsigned intLCDCON2;// 04

unsigned intLCDCON3;// 08

.....................

}LCDreg ;

// LCD register value

#define MODE_TFT_24BIT(224)

#define LCD_XSIZE_TFT(800)

#define LCD_YSIZE_TFT(480)

#define ARRAY_SIZE_TFT_24BIT(SCR_XSIZE*4*SCR_YSIZE)

#define HOZVAL_TFT(LCD_XSIZE_TFT-1)

#define LINEVAL_TFT(LCD_YSIZE_TFT-1)

#define MVAL(13)

#define MVAL_USED(0)

#define VBPD((32-1)&0xff)

#define VFPD((11-1)&0xff)

#define VSPW((2-1) &0x3f)

#define HBPD((88-1)&0x7f)

#define HFPD((40-1)&0xff)

#define HSPW((128-1)&0xff)

#define CLKVAL_TFT(1)

#define M5D(n)((n) & 0x1fffff)

U32* pLCDBuffer24=(U32*)FRAMEBUF_DMA_BASE;

U32* picData;

volatile LCDreg *s2410LCD = (LCDreg *)LCD_BASE;

volatile IOPreg *s2410IOP= (IOPreg *)IOP_BASE;

int nCol = 800;//象素列数

int nRow = 480;//象素行数

U32* picDataT=NULL;

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

void lcd_Main(void)

{

char sel;

Uart_Printf("Lcd_Driver ");

lcd_port_init();

lcd_regs_init();

Uart_Printf("select one Picture to show(1 2 3 4 5 0) ");

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("Input 1 2 3 4 5 0 ");

}

lcd_display();

Uart_Printf("select one Picture to show(1 2 3 4 5 0) ");

}

Uart_Printf("Exit");

//lcd_close();

}

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

void lcd_port_init(void)

{

// LCD port initialize.

s2410IOP->GPCUP= 0xFFFFFFFF;

s2410IOP->GPCCON = 0xAAAAAAAA;

s2410IOP->GPDUP= 0xFFFFFFFF;

s2410IOP->GPDCON = 0xAAAAAAAA;

s2410IOP->GPGCON &= ~(3 << 8);/**//* Set LCD_PWREN as output*/

s2410IOP->GPGCON |=(1 << 8);

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

}

3、控制寄存器设置:

void lcd_regs_init(void)

{

#ifdef MODE_TFT_24BIT

s2410LCD->LCDCON1=(1<<8) |//* VCLK = HCLK / ((CLKVAL + 1) * 2) -> About 7 Mhz

(MVAL_USED<<7) |//* 0 : Each Frame

(3<<5) |// TFT LCD Pannel

(13<<1) |//Y: // 24bpp Mode

(0<<0) ;// Disable LCD Output

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: LSB valid

(0<< 11) |// FRM565 MODE: 5:5:5:1 Format

(0<< 10) |// INVVCLK: VCLK Falling Edge

(0<<9) |// INVVLINE: Inverted Polarity

(0<<8) |// INVVFRAME: Inverted Polarity

(0<<7) |// INVVD: Normal

(0<<6) |// INVVDEN: Normal

(0<<5) |// INVPWREN: Normal

(0<<4) |// INVENDLINE: Normal

(0<<3) |// PWREN: Disable PWREN

(0<<2) |// ENLEND: Disable LEND signal

(0<<1) |// BSWP: Swap Disable

(0<<0) ;// HWSWP: Swap Enable

*/

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、居中显示图片:

void lcd_display(void)

{

int y;

int pw, ph;

int sw=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

...{

memcpy((pBt+800*y),(char*)pdata,nCol*4);//一行一行显示

pdata = (U32*)(pdata+nCol);

}

s2410LCD->LCDCON1 |= 0;

}

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

void lcd_clear()

{

int y=0;

U32* pdata = (U32*)(bgData+2);

for(y=0; y<480; ++y)

{

memcpy((pLCDBuffer24+800*y),(char*)pdata,800*4);

pdata = (U32*)(pdata+800);

}

}

void get_XY(void)

{

nCol = picData[0];

nRow = picData[1];

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

}

可能会用到的工具/仪表
本站简介 | 意见建议 | 免责声明 | 版权声明 | 联系我们
CopyRight@2024-2039 嵌入式资源网
蜀ICP备2021025729号