加入收藏 | 设为首页 | 会员中心 | 我要投稿 | RSSRSS-巴斯仪表网
您当前的位置:首页 > 电子发烧 > 单片机学习

s3c2410 LCD图片显示

时间:2013-09-08  来源:123485.com  作者:9stone

        最近研究了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);
}


分享到:
来顶一下
返回首页
返回首页
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表
栏目导航->单片机学习
  • 电子应用基础
  • 电源技术
  • 无线传输技术
  • 信号处理
  • PCB设计
  • EDA技术
  • 单片机学习
  • 电子工具设备
  • 技术文章
  • 精彩拆解欣赏
  • 推荐资讯
    使用普通运放的仪表放大器
    使用普通运放的仪表放
    3V与5V混合系统中逻辑器接口问题
    3V与5V混合系统中逻辑
    数字PID控制及其改进算法的应用
    数字PID控制及其改进
    恶劣环境下的高性价比AD信号处理数据采集系统
    恶劣环境下的高性价比
    栏目更新
    栏目热门