关于S3C2410裸机驱动LCD的问题

amote   2009-9-24 11:09 楼主
/**************************************************************
320×240 16Bpp TFT LCD功能模块初始化
**************************************************************/
void Lcd_Init(void)
{
        rLCDCON1=(CLKVAL_TFT_240320<<8)|(MVAL_USED<<7)|(3<<5)|(12<<1)|0;
            // TFT LCD panel,12bpp TFT,ENVID=off
        rLCDCON2=(VBPD_240320<<24)|(LINEVAL_TFT_240320<<14)|(VFPD_240320<<6)|(VSPW_240320);
        rLCDCON3=(HBPD_240320<<19)|(HOZVAL_TFT_240320<<8)|(HFPD_240320);
        rLCDCON4=(MVAL<<8)|(HSPW_240320);
        rLCDCON5=(1<<11)|(0<<9)|(0<<8)|(0<<6)|(BSWP<<1)|(HWSWP);       
        rLCDSADDR1=(((U32)LCD_BUFER>>22)<<21)|M5D((U32)LCD_BUFER>>1);
        rLCDSADDR2=M5D( ((U32)LCD_BUFER+(SCR_XSIZE_TFT_240320*LCD_YSIZE_TFT_240320*2))>>1 );
        rLCDSADDR3=(((SCR_XSIZE_TFT_240320-LCD_XSIZE_TFT_240320)/1)<<11)|(LCD_XSIZE_TFT_240320/1);
        rLCDINTMSK|=(3); // MASK LCD Sub Interrupt
        rLPCSEL&=(~7); // Disable LPC3600
        rTPAL=0; // Disable Temp Palette

}
这段代码是我的初始化代码。其中的LCD_BUFER是声明的二维数组,通过rLCDSADDR这几个寄存器,设置了显存的地址。这样我写入LCD_BUFER数组中的数据,就可以来控制液晶的现实内容。
但是现在我调用Glib_FilledRectangle(100,100,200,200,0x07ff);这个函数,屏幕上也确实是显示了一个正方形。但是
它显示的位置,并不是我设置的100 100 200 200。而是在屏幕偏右的方向。也就是说这个地址发生了偏移。请问这是为什么?第一次发问,请大侠们帮着解决一下。我直接用的LCD_BUFER初始化的rLCDSADDR寄存器。也没有用到什么MMU。

回复评论 (11)

建议你贴出Glib_FilledRectangle()函数的代码。你的这个坐标是不是固定坐标,而是相对坐标,相对坐标是要在buffer的起始地址的基础上加上绝对坐标才行
点赞  2009-9-27 14:27
跟扫描方式有关系1?
点赞  2009-9-27 14:47
首先把你的屏幕填满 ,看看有没有偏移来确定是不是初始化的问题;初始化没问题的话就是你画线函数的问题了


**************************
飞凌嵌入式 www.witech.com.cn   
**************************
点赞  2009-9-27 16:39
#include
#include "2410addr.h"
#include "2410lib.h"
#include "def.h"
#include "2410slib.h"
#include "LCD.h"
volatile unsigned short LCD_BUFER[SCR_YSIZE_TFT_240320][SCR_XSIZE_TFT_240320];

void Lcd_Port_Init(void)
{
    rGPCUP=0xffffffff; // Disable Pull-up register
    rGPCCON=0xaaaa56a9; //Initialize VD[7:0],LCDVF[2:0],VM,VFRAME,VLINE,VCLK,LEND

    rGPDUP=0xffffffff; // Disable Pull-up register
    rGPDCON=0xaaaaaaaa; //Initialize VD[15:8]
}

void Lcd_Init(void)
{
        rLCDCON1=(CLKVAL_TFT_240320<<8)|(MVAL_USED<<7)|(3<<5)|(12<<1)|0;
            // TFT LCD panel,12bpp TFT,ENVID=off
        rLCDCON2=(VBPD_240320<<24)|(LINEVAL_TFT_240320<<14)|(VFPD_240320<<6)|(VSPW_240320);
        rLCDCON3=(HBPD_240320<<19)|(HOZVAL_TFT_240320<<8)|(HFPD_240320);
        rLCDCON4=(MVAL<<8)|(HSPW_240320);
        rLCDCON5=(1<<11)|(0<<9)|(0<<8)|(0<<6)|(BSWP<<1)|(HWSWP);        //FRM5:6:5,HSYNC and VSYNC are inverted
        rLCDSADDR1=(((U32)LCD_BUFER>>22)<<21)|M5D((U32)LCD_BUFER>>1);
        rLCDSADDR2=M5D( ((U32)LCD_BUFER+(SCR_XSIZE_TFT_240320*LCD_YSIZE_TFT_240320*2))>>1 );
        rLCDSADDR3=(((SCR_XSIZE_TFT_240320-LCD_XSIZE_TFT_240320)/1)<<11)|(LCD_XSIZE_TFT_240320/1);
        rLCDINTMSK|=(3); // MASK LCD Sub Interrupt
        rLPCSEL&=(~7); // Disable LPC3600
        rTPAL=0; // Disable Temp Palette
}

void Lcd_EnvidOnOff(int onoff)
{
    if(onoff==1)
        rLCDCON1|=1; // ENVID=ON
    else
        rLCDCON1 =rLCDCON1 & 0x3fffe; // ENVID Off
}

void Lcd_Lpc3600Enable(void)
{
    rLPCSEL&=~(7);
    rLPCSEL|=(7); // 240320,Enable LPC3600
}   

void Lcd_PowerEnable(int invpwren,int pwren)
{
    //GPG4 is setted as LCD_PWREN
    rGPGUP = rGPGUP|(1<<4); // Pull-up disable
    rGPGCON = rGPGCON|(3<<8); //GPG4=LCD_PWREN
    //Enable LCD POWER ENABLE Function
    rLCDCON5 = rLCDCON5&(~(1<<3))|(pwren<<3);   // PWREN
    rLCDCON5=rLCDCON5&(~(1<<5))|(invpwren<<5);   // INVPWREN
}

/**************************************************************
320×240 8Bpp TFT LCD 颜色初始化
**************************************************************/
void Lcd_Palette_Init(void)
{
    unsigned char cdata, p_red, p_green, p_blue;
    U32 *palette;
   
        //#define PALETTE     0x4d000400    //Palette start address
    palette=(U32 *)PALETTE;
    *palette++=0; //black
    for(cdata=1;cdata<255;cdata++)
    {
                p_red=(cdata & 0xe0);
                p_green=(cdata & 0x1c);
                p_blue=(cdata & 0x03);
            *palette++=((U32)((p_red<<8)|(p_green<<6)|(p_blue<<3)));
    }
    *palette=0xffff; //white
}

/**************************************************************
320×240 16Bpp TFT LCD移动观察窗口
**************************************************************/
void Lcd_MoveViewPort(int vx,int vy)
{
    U32 addr;

    SET_IF();
        #if (LCD_XSIZE_TFT_240320<32)
                while((rLCDCON1>>18)<=1); // if x<32
        #else       
                while((rLCDCON1>>18)==0); // if x>32
        #endif
   
    addr=(U32)LCD_BUFER+(vx*2)+vy*(SCR_XSIZE_TFT_240320*2);
        rLCDSADDR1= ( (addr>>22)<<21 ) | M5D(addr>>1);
        rLCDSADDR2= M5D(((addr+(SCR_XSIZE_TFT_240320*LCD_YSIZE_TFT_240320*2))>>1));
        CLR_IF();
}   

/**************************************************************
320×240 16Bpp TFT LCD移动观察窗口
**************************************************************/
void MoveViewPort(void)
{
    int vx=0,vy=0,vd=1;

    Uart_Printf("\n*Move the LCD view windos:\n");
    Uart_Printf(" press 8 is up\n");
    Uart_Printf(" press 2 is down\n");
    Uart_Printf(" press 4 is left\n");
    Uart_Printf(" press 6 is right\n");
    Uart_Printf(" press Enter to exit!\n");

    while(1)
    {
            switch(Uart_Getch())
            {
            case '8':
            if(vy>=vd)vy-=vd;                      
        break;

            case '4':
                if(vx>=vd)vx-=vd;
            break;

            case '6':
                if(vx<=(SCR_XSIZE_TFT_240320-LCD_XSIZE_TFT_240320-vd))vx+=vd;               
               break;

            case '2':
                if(vy<=(SCR_YSIZE_TFT_240320-LCD_YSIZE_TFT_240320-vd))vy+=vd;               
               break;

            case '\r':
               return;

            default:
            break;
                }
        Uart_Printf("vx=%3d,vy=%3d\n",vx,vy);
        Lcd_MoveViewPort(vx,vy);
    }
}

/**************************************************************
320×240 16Bpp TFT LCD单个象素的显示数据输出
**************************************************************/
void PutPixel(U32 x,U32 y,U32 c)
{
        if ( (x < SCR_XSIZE_TFT_240320) && (y < SCR_YSIZE_TFT_240320) )
        LCD_BUFER[(y)][(x)] = c;
}

/**************************************************************
320×240 16Bpp TFT LCD全屏填充特定颜色单元或清屏
**************************************************************/
void Lcd_ClearScr(U16 c)
{
        unsigned int x,y ;
               
    for( y = 0 ; y < SCR_YSIZE_TFT_240320 ; y++ )
    {
            for( x = 0 ; x < SCR_XSIZE_TFT_240320 ; x++ )
            {
                        LCD_BUFER[y][x] = c;
            }
    }
}

/**************************************************************
LCD屏幕显示垂直翻转
// LCD display is flipped vertically
// But, think the algorithm by mathematics point.
//   3I2
//   4 I 1
//  --+--   <-8 octants  mathematical cordinate
//   5 I 8
//   6I7
**************************************************************/
void Glib_Line(int x1,int y1,int x2,int y2,int color)
{
        int dx,dy,e;
        dx=x2-x1;
        dy=y2-y1;
   
        if(dx>=0)
        {
                if(dy >= 0) // dy>=0
                {
                        if(dx>=dy) // 1/8 octant
                        {
                                e=dy-dx/2;
                                while(x1<=x2)
                                {
                                        PutPixel(x1,y1,color);
                                        if(e>0){y1+=1;e-=dx;}       
                                        x1+=1;
                                        e+=dy;
                                }
                        }
                        else                // 2/8 octant
                        {
                                e=dx-dy/2;
                                while(y1<=y2)
                                {
                                        PutPixel(x1,y1,color);
                                        if(e>0){x1+=1;e-=dy;}       
                                        y1+=1;
                                        e+=dx;
                                }
                        }
                }
                else                   // dy<0
                {
                        dy=-dy;   // dy=abs(dy)

                        if(dx>=dy) // 8/8 octant
                        {
                                e=dy-dx/2;
                                while(x1<=x2)
                                {
                                        PutPixel(x1,y1,color);
                                        if(e>0){y1-=1;e-=dx;}       
                                        x1+=1;
                                        e+=dy;
                                }
                        }
                        else                // 7/8 octant
                        {
                                e=dx-dy/2;
                                while(y1>=y2)
                                {
                                        PutPixel(x1,y1,color);
                                        if(e>0){x1+=1;e-=dy;}       
                                        y1-=1;
                                        e+=dx;
                                }
                        }
                }       
        }
        else //dx<0
        {
                dx=-dx;                //dx=abs(dx)
                if(dy >= 0) // dy>=0
                {
                        if(dx>=dy) // 4/8 octant
                        {
                                e=dy-dx/2;
                                while(x1>=x2)
                                {
                                        PutPixel(x1,y1,color);
                                        if(e>0){y1+=1;e-=dx;}       
                                        x1-=1;
                                        e+=dy;
                                }
                        }
                        else                // 3/8 octant
                        {
                                e=dx-dy/2;
                                while(y1<=y2)
                                {
                                        PutPixel(x1,y1,color);
                                        if(e>0){x1-=1;e-=dy;}       
                                        y1+=1;
                                        e+=dx;
                                }
                        }
                }
                else                   // dy<0
                {
                        dy=-dy;   // dy=abs(dy)

                        if(dx>=dy) // 5/8 octant
                        {
                                e=dy-dx/2;
                                while(x1>=x2)
                                {
                                        PutPixel(x1,y1,color);
                                        if(e>0){y1-=1;e-=dx;}       
                                        x1-=1;
                                        e+=dy;
                                }
                        }
                        else                // 6/8 octant
                        {
                                e=dx-dy/2;
                                while(y1>=y2)
                                {
                                        PutPixel(x1,y1,color);
                                        if(e>0){x1-=1;e-=dy;}       
                                        y1-=1;
                                        e+=dx;
                                }
                        }
                }       
        }
}

/**************************************************************
在LCD屏幕上用颜色填充一个矩形
**************************************************************/
void Glib_FilledRectangle(int x1,int y1,int x2,int y2,int color)
{
    int i;

    for(i=y1;i<=y2;i++)
        Glib_Line(x1,i,x2,i,color);
}

/**************************************************************
**************************************************************/
void Test_Lcd_Tft_16Bpp_240_320(void)
{
        //unsigned int x,y ;
        //U32 c;
       
        #define DELAY_TIME                36000

        #ifdef DEBUG
            Uart_Printf("\nTest LTS350Q1_PE1 & LQ035Q7DB02 (TFT LCD)!\n");
        #endif       

    Lcd_Port_Init();
    Lcd_Init();
    Lcd_EnvidOnOff(1);                //turn on vedio

        Lcd_ClearScr(28);                //fill all screen with some color
       
/*        Glib_FilledRectangle( 12, 12, 228, 308,0x0000);                //fill a Rectangle with some color

        Glib_FilledRectangle( 24, 24, 88,296,0x001f);                //fill a Rectangle with some color
        Glib_FilledRectangle( 89, 24,152,296,0x07e0);                //fill a Rectangle with some color
        Glib_FilledRectangle(153, 24,216,296,0xf800);                //fill a Rectangle with some color

        Glib_FilledRectangle( 70, 110, 170, 210,0xf7e0);                //fill a Rectangle with some color
        Glib_FilledRectangle( 90, 130, 150, 190,0x07ff);                //fill a Rectangle with some color
        Glib_FilledRectangle(110, 150, 130, 170,0xf81f);                //fill a Rectangle with some color*/

        #ifdef DEBUG
            Uart_Printf( "\nrGPBCON=0x%x\n", rGPBCON );
            Uart_Printf( "\trGPBUP=0x%x\n", rGPBUP );
            Uart_Printf( "rGPCCON=0x%x\n", rGPCCON );
            Uart_Printf( "\trGPCUP=0x%x\n", rGPCUP );
            Uart_Printf( "rGPDCON=0x%x\n", rGPDCON );
            Uart_Printf( "\trGPDUP=0x%x\n", rGPDUP );
            Uart_Printf( "rGPGCON=0x%x\n", rGPGCON );
            Uart_Printf( "\trGPGUP=0x%x\n\n", rGPGUP );

            Uart_Printf( "rLCDCON1=0x%x\n", rLCDCON1 );
            Uart_Printf( "rLCDCON2=0x%x\n", rLCDCON2 );
            Uart_Printf( "rLCDCON3=0x%x\n", rLCDCON3 );
            Uart_Printf( "rLCDCON4=0x%x\n", rLCDCON4 );
            Uart_Printf( "rLCDCON5=0x%x\n\n", rLCDCON5 );

            Uart_Printf( "rLCDSADDR1=0x%x\n", rLCDSADDR1 );
            Uart_Printf( "rLCDSADDR2=0x%x\n", rLCDSADDR2 );
            Uart_Printf( "rLCDSADDR3=0x%x\n\n", rLCDSADDR3 );
           
            Uart_Printf( "rLCDINTMSK=0x%x\n", rLCDINTMSK );
            Uart_Printf( "rLPCSEL=0x%x\n", rLPCSEL );
            Uart_Printf( "rTPAL=0x%x\n\n", rTPAL );
        #endif       

    //Paint_Bmp( 0, 0, 240, 320, xyx_240_320 );                //paint a bmp
}
//*************************************************************
代码都贴在这了。大家帮我看看。谢谢。二楼的兄弟帮我看一下。
点赞  2009-9-28 15:45
提示: 作者被禁止或删除 内容自动屏蔽
点赞  2009-9-29 22:22
100,100,200,200,这样设置本来就会偏右的吧。可能没明白楼主的意思。
点赞  2009-9-29 22:57
100 100 200 200   但是屏幕上显示的位置并不是我设置的这个位置。
而且我将  存储控制像素的那些数据的数组,全部清零后。屏幕并没有被清掉。
而且横着, 竖着 各有一条大黑条。
点赞  2009-9-30 08:48
是不是你的hbp那些参数不对?
点赞  2009-9-30 14:28
  1. // Test LCD display status with R.G.B and White color.
  2.         for (i=0; i
  3.         {
  4.                 for (j=0; j
  5.                 {
  6.                         if (j
  7.                                         FBuf->pixel[i][j]=0xffffff;                               
  8.                         else                               
  9.                                         FBuf->pixel[i][j]=0xff0000;
  10.                                
  11.                 }
  12.         }

  13.         for (i=LCD_YSIZE_TFT/2; i
  14.         {
  15.                 for (j=0; j
  16.                 {
  17.                         if (j
  18.                                         FBuf->pixel[i][j]=0x00ff00;
  19.                                
  20.                         else                               
  21.                                         FBuf->pixel[i][j]=0xff;
  22.                                
  23.                 }
  24.         }


贴一个代码给你 慢慢耍吧

--
非得用那个函数吗  ?  你得到要实现什么功能!      
点赞  2009-9-30 15:41
位置不对有可能是Front-porch和Back-porch的问题,现在我也遇到有点偏了。
点赞  2009-9-30 15:59
还没搞掂呀,兄弟真幸苦,帮你顶下。
点赞  2009-9-30 22:44
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复