s3c2440 LCD及觸摸屏的學習筆記(1)

所用的LCD爲TopPoly-TD035STED4(TFT)型號,240*320的

其VCLK爲6.39MHz。 根據s3c2440手冊s3c2440處理LCD的時鐘源是HCLK,通過寄存器LCDCON1中的CLKVAL可以調整VCLK頻率大小,它的公式爲:VCLKHCLK÷[(CLKVAL1)×2],程序的內部分頻爲FCLK=400MHz、HCLK=100MHz、PCLK=50MHz(MPLLCON=(92<<12)|(1<<4)|1;),因此得到CLKVAL取整爲6。

注:(LCD一般需要三個時序信號:VSYNCHSYNCVCLKVSYNC是垂直同步信號,在每進行一個幀(即一個屏)的掃描之前,該信號就有效一次,由該信號可以確定LCD的場頻,即每秒屏幕刷新的次數(單位Hz)。HSYNC是水平同步信號,在每進行一行的掃描之前,該信號就有效一次,由該信號可以確定LCD的行頻,即每秒屏幕從左到右掃描一行的次數(單位Hz)。VCLK是像素時鐘信號。

其中VSYNC是幀同步信號,VSYNC每發出1個脈衝,都意味着新的1屏視頻資料開始發送。而HSYNC爲行同步 信號,每個HSYNC脈衝都表明新的1行視頻資料開始發送。而VDEN則用來標明視頻資料的有效,VCLK是用來鎖存視頻資料的像數時鐘。網上搜到的資料來解釋這幾個時序信號。

可以查看s3c2440手冊‘Figure 15-6. TFT LCD Timing Example’圖)

 通過上圖可以得到:

代碼
#define LCD_WIDTH   240              //屏幕的寬
#define LCD_HEIGHT  320              //屏幕的高
 
//垂直同步信號的脈寬、後肩和前肩-----這些值是根據TopPoly-TD035STED4.pdf文件中的13頁的表
#define VSPW      1 //(3-1)
#define VBPD      1 //(15-1)
#define VFPD      1 //(12-1)

//水平同步信號的脈寬、後肩和前肩-----這些值是根據TopPoly-TD035STED4.pdf文件中的13頁的表
#define HSPW       (10-1)
#define HBPD       (20-1)
#define HFPD        (10-1)

//顯示尺寸
#define LINEVAL  (LCD_HEIGHT-1)
#define HOZVAL   (LCD_WIDTH-1)

注:(對於一個已知尺寸LCD屏,只要確定了VCLK值,行頻和場頻就應該知道了。但這樣還不行的,因爲在每一幀時鐘信號中,還會有一些與屏顯示無關的時鐘出現,這就給確定行頻和場頻帶來了一定的複雜性。如在HSYNC信號先後會有水平同步信號前肩(HFPD)和水平同步信號後肩(HBPD)出現,在VSYNC信號先後會有垂直同步信號前肩(VFPD)和垂直同步信號後肩(VBPD)出現,在這些信號時序內,不會有有效像素信號出現,另外HSYNCVSYNC信號有效時,其電平要保持一定的時間,它們分別叫做水平同步信號脈寬HSPW和垂直同步信號脈寬VSPW,這段時間也不能有像素信號。因此計算行頻和場頻時,一定要包括這些信號。HBPDHFPDHSPW的單位是一個VCLK的時間,而VSPWVFPDVBPD的單位是掃描一行所用的時間。也是網上搜的。

 這些信號(VSPWVFPDVBPDLINEVALHBPDHFPDHSPWHOZVAL是通過寄存器LCDCON2LCDCON3LCDCON4來配置的,具體查看s3c2440的手冊。

LCDCON1寄存器:

               LINECNT :當前行掃描計數器值,標明當前掃描到了多少行。
               CLKVAL :決定VCLK的分頻 比(上面已經提到過)。LCD控制器輸出的VCLK是直接由系統總線(AHB)
                             的工作頻率HCLK(一般爲100MHZ)直接分頻得到的。做爲240*320的TFT屏,應保證得
                             出的VCLK在5~10MHz之間。
                MMODE :VM信號的觸發模式(僅對STN屏有效,對TFT屏無意義。)PNRMODE :選擇當前的顯示模式,
                             對於TFT屏而言,應選擇[11],即TFT LCD panel。

                BPPMODE :選擇色彩模式,對於真彩顯示而言,選擇16bpp(64K色)即可滿足要求。

                ENVID 使能LCD信號輸出

 LCDCON5寄存器:

                 VSTATUS :當前VSYNC信號掃描狀態,指明當前VSYNC同步信號處於何種掃描階段。

                 HSTATUS 當前HSYNC信號掃描狀態,指明當前HSYNC同步信號處於何種掃描階段。
                 BPP24BL 設定24bpp顯示模式時,視頻資料在顯示緩衝區中的排列順序(即低位有效還是高位有效)。
                                 對於16bpp的 64K色顯示模式,該設置位無意義。
                 FRM565 對於16bpp顯示模式,有2中形式,一種是RGB=5:5:5:1,另一種是5:6:5。後一 種模式最爲
                                常用,它的含義是表示64K種色彩的16bit RGB資料中,紅色(R)佔了5bit,綠色(G)佔了
                                6bit,蘭色(B)佔了5bit。
                 INVVCLK 、INVLINE 、INVFRAME 、INVVD :通過前面提到的‘Figure 15-6’的時序圖,我們知
                                 道,CPU的LCD控制器輸出的時序默認是正脈衝,而LCD需要VSYNC(VFRAME)、
                                 VLINE(HSYNC)均爲負脈衝,因此 INVLINE 和 INVFRAME 必須設爲“1 ”,即選擇反相輸
                                  出。 INVVDEN , INVPWREN , INVLEND 的功能同前面的類似。
                 PWREN :LCD電源使能控制。在CPU LCD控制器的輸出信號中,有一個電源使能管腳LCD_PWREN,用
                               來做爲LCD屏電源的開關信號。
                 ENLEND 對普通的TFT屏無效,可以不考慮。

                 INVVDENINVPWRENINVLEND:是否翻轉這些信號,一般爲正常,不需要翻轉。

                  BSWP 、HWSWP : 爲字節(Byte)或半字(Half-Word)交換使能。由於不同的GUI對
                                             FrameBuffer(顯示緩衝區)的管理不同,必要時需要通過調整 BSWP 和 HWSWP
                                             來適應GUI。
因此:

代碼
//for LCDCON1
#define CLKVAL_TFT          4            //設置時鐘信號
#define MVAL_USED          0            //
#define PNRMODE_TFT      3            //TFT型LCD
#define BPPMODE_TFT      13           //24位TFT型LCD

//for LCDCON5  
#define BPP24BL        0       //32位數據表示24位顏色值時,低位數據有效,高8位無效
#define INVVCLK        0       //像素值在VCLK下降沿有效
#define INVVLINE       1       //翻轉HSYNC信號
#define INVVFRAME      1       //翻轉VSYNC信號
#define INVVD          0       //正常VD信號極性
#define INVVDEN        0       //正常VDEN信號極性
#define PWREN          1       //使能PWREN信號
#define BSWP           0       //顏色數據字節不交換
#define HWSWP          0       //顏色數據半字不交換

rLCDCON1=(CLKVAL_TFT<<8)|(MVAL_USED<<7)|(PNRMODE_TFT<<5)|(BPPMODE_TFT<<1)|0;
rLCDCON2=(VBPD<<24)|(LINEVAL<<14)|(VFPD<<6)|(VSPW);
rLCDCON3=(HBPD<<19)|(HOZVAL<<8)|(HFPD);
rLCDCON4=(HSPW);//

rLCDCON5 = (BPP24BL<<12| (INVVCLK<<10| (INVVLINE<<9| (INVVFRAME<<8| (0<<7| (INVVDEN<<6| (PWREN<<3)  |(BSWP<<1| (HWSWP);

LCDSADDR1LCDSADDR2
              LCDBASEL=LCDBASEU+(PAGEWITH+OFFSIZE)×(LINEVAL+1)
LCDSADDR3寄存器:
                  OFFSIZE:用於虛擬屏幕的偏移長度,如果我們不使用虛擬屏幕,就把它置爲0 。
                   PAGEWIDTH:定義了視口的寬,單位是半字,如在上面的例子中,PAGEWIDTH應該爲320×32÷16

代碼
#define M5D(n)  ((n) & 0x1fffff)     //用於設置顯示緩存區時,取低21位地址
//定義顯示緩存區
volatile U32 LCD_BUFFER[LCD_HEIGHT][LCD_WIDTH];
rLCDSADDR1
=(((U32)LCD_BUFFER>>22)<<21)|M5D((U32)LCD_BUFFER>>1);
rLCDSADDR2
=M5D((M5D((U32)LCD_BUFFER>>1)+((LCD_WIDTH*32/16+0)*320)));
rLCDSADDR3
=(LCD_WIDTH*32/16)&0x7ff;//參考s3c2440的手冊

簡單程序實現:

代碼
//***************************************************
#include "def.h"
#include 
"option.h"
#include 
"2440addr.h"     
#include 
"2440lib.h"
#include 
"2440slib.h"      
//================================

#define M5D(n)  ((n) & 0x1fffff)     //用於設置顯示緩存區時,取低21位地址

#define LCD_WIDTH   240              //屏幕的寬
#define LCD_HEIGHT  320              //屏幕的高
 
//垂直同步信號的脈寬、後肩和前肩-----這些值是根據TopPoly-TD035STED4.pdf文件中的13頁的表
#define VSPW      1 //(3-1)
#define VBPD      1 //(15-1)
#define VFPD      1 //(12-1)

//水平同步信號的脈寬、後肩和前肩-----這些值是根據TopPoly-TD035STED4.pdf文件中的13頁的表
#define HSPW       (10-1)
#define HBPD       (20-1)
#define HFPD        (10-1)

//顯示尺寸
#define LINEVAL  (LCD_HEIGHT-1)
#define HOZVAL   (LCD_WIDTH-1)

//for LCDCON1
#define CLKVAL_TFT          4            //設置時鐘信號
#define MVAL_USED          0            //
#define PNRMODE_TFT      3            //TFT型LCD
#define BPPMODE_TFT      13           //24位TFT型LCD

//for LCDCON5  
#define BPP24BL        0       //32位數據表示24位顏色值時,低位數據有效,高8位無效
#define INVVCLK        0       //像素值在VCLK下降沿有效
#define INVVLINE       1       //翻轉HSYNC信號
#define INVVFRAME      1       //翻轉VSYNC信號
#define INVVD          0       //正常VD信號極性
#define INVVDEN        0       //正常VDEN信號極性
#define PWREN          1       //使能PWREN信號
#define BSWP           0       //顏色數據字節不交換
#define HWSWP          0       //顏色數據半字不交換

//定義顯示緩存區
volatile U32 LCD_BUFFER[LCD_HEIGHT][LCD_WIDTH];
//**********************************************************

//延時程序
void delay(int a)
{
       
int k;
       
for(k=0;k<a;k++)              ;
}
   
//繪製屏幕背景顏色,顏色爲c
void Brush_Background( U32 c)
{
   
int x,y ;
    
for( y = 0 ; y < LCD_HEIGHT ; y++ )
    {
        
for( x = 0 ; x < LCD_WIDTH ; x++ )
        {
            LCD_BUFFER[y][x] 
= c ;
        }
    }
}

 
void init_port_lcd()
 {
    rGPCCON 
= 0xaaaaaaaa;       
        rGPCUP  
= 0xffff;     // The pull up function is disabled GPC[15:0] 

        
//*** PORT D GROUP
        
//Ports  : GPD15 GPD14 GPD13 GPD12 GPD11 GPD10 GPD9 GPD8 GPD7 GPD6 GPD5 GPD4 GPD3 GPD2 GPD1 GPD0
        
//Signal : VD23  VD22  VD21  VD20  VD19  VD18  VD17 VD16 VD15 VD14 VD13 VD12 VD11 VD10 VD9  VD8
        
//Binary : 10    10  , 10    10  , 10    10  , 10   10 , 10   10 , 10   10 , 10   10 ,10   10
        rGPDCON = 0xaaaaaaaa;       
        rGPDUP  
= 0xffff

    rLCDCON1
=(CLKVAL_TFT<<8)|(MVAL_USED<<7)|(PNRMODE_TFT<<5)|(BPPMODE_TFT<<1)|0;
    rLCDCON2
=(VBPD<<24)|(LINEVAL<<14)|(VFPD<<6)|(VSPW);
    rLCDCON3
=(HBPD<<19)|(HOZVAL<<8)|(HFPD);
    rLCDCON4
=(HSPW);
    
//rLCDCON4 =  (5<< 0);
    rLCDCON5 = (BPP24BL<<12| (INVVCLK<<10| (INVVLINE<<9| (INVVFRAME<<8| (0<<7| (INVVDEN<<6| (PWREN<<3)  |(BSWP<<1| (HWSWP);

    rLCDSADDR1
=(((U32)LCD_BUFFER>>22)<<21)|M5D((U32)LCD_BUFFER>>1);
    rLCDSADDR2
=M5D( (M5D((U32)LCD_BUFFER>>1)+((LCD_WIDTH*32/16+0)*320))  );//LCD_WIDTH*LCD_HEIGHT*4
    rLCDSADDR3=(LCD_WIDTH*32/16)&0x7ff;//參考s3c2440的手冊
    rLCDINTMSK|=(3);      // 屏蔽LCD中斷
    
//rTCONSEL = 0;            //無效LPC3480
        rTCONSEL   &= (~7);
 

        rTPAL     
= 0x0;
        rTCONSEL 
&= ~((1<<4| 1);

    rGPGUP
=rGPGUP&(~(1<<4))|(1<<4);      //GPG4上拉電阻無效
    rGPGCON=rGPGCON&(~(3<<8))|(3<<8); //設置GPG4爲LCD_PWREN
    rGPGDAT = rGPGDAT | (1<<4) ;               //GPG4置1

    rLCDCON5
=rLCDCON5&(~(1<<3))|(1<<3);   //有效PWREN信號
    rLCDCON5=rLCDCON5&(~(1<<5))|(0<<5);   //PWREN信號極性不翻轉

    rLCDCON1
|=1;                   //LCD開啓
 }


int Main(int argc, char **argv)
{
    
int i;
    U8 key;
    U32 mpll_val
=0;
    
int data;
  
    mpll_val 
= (92<<12)|(1<<4)|(1);
    
    
//init FCLK=400M, so change MPLL first
    ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);
    ChangeClockDivider(key, 
12);    

    
//ChangeClockDivider(1,1);    // 1:2:4    FCLK:HCLK:PCLK
        
// rCLKDIVN=0x4;    //  1:4:4
        
//ChangeMPllValue(82,2,1);     //FCLK=135.0Mhz     
    
//ChangeMPllValue(82,1,1);     //FCLK=180.0Mhz     
        
//ChangeMPllValue(161,3,1);    //FCLK=202.8Mhz 
        
//ChangeMPllValue(117,1,1);    //FCLK=250.0Mhz 
        
//ChangeMPllValue(122,1,1);    //FCLK=260.0Mhz 
        
//ChangeMPllValue(125,1,1);    //FCLK=266.0Mhz 
        
//ChangeMPllValue(127,1,1);    //FCLK=270.0Mhz  
    
        
//MMU_EnableICache();
        
//MMU_EnableDCache();
    
        MMU_DisableICache();
        MMU_DisableDCache();

    init_port_lcd();
    
while(1)
    {
        
//黑色背景
        Brush_Background(0x0000);
        delay(
5000000);
        
//白色背景
        Brush_Background(0xffffff);
        delay(
5000000);
        
//藍色背景
        Brush_Background(0x00ff);
        delay(
5000000);
        
//綠色背景
        Brush_Background(0xff00);
        delay(
5000000);
        
//黃色背景
        Brush_Background(0xffff00);
        delay(
5000000);
    }
   
return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章