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

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

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

关键模块如下:

0.全局变量的定义:

 

#define  DMA_BUFFER_BASE            0xAC000000
#define  DMA_PHYSICAL_BASE        0x35000000   //  S3C2410X01 0x30000000

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

#define  IOP_BASE      0x56000000  //  0x56000000

typedef 
struct    {
    unsigned 
int  GPACON;        // 00
    unsigned int  GPADAT;
    unsigned 
int  PAD1[2];
    ...................
    }
IOPreg;  
 
//  Define LCD type of S3C2400X01
#define  TFT24BPP    3
#define  LCDTYPE     TFT24BPP    //  define LCD type as upper definition.
//
//  Registers : LCD Controller
//

#define  LCD_BASE      0x4D000000  //  0x4D000000
typedef 
struct    {
    unsigned 
int  LCDCON1;        // 00
    unsigned int  LCDCON2;        // 04
    unsigned int  LCDCON3;        // 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<nRow; ++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);
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值