zoukankan      html  css  js  c++  java
  • LCD深度剖析

    LCD 深度剖析

    来源:http://blog.csdn.net/hardy_2009/article/details/6922900

              http://blog.csdn.net/jaylondon/article/details/6363741

               http://blog.csdn.net/zhaocj/article/details/5397180

              http://www.cnblogs.com/stardream/articles/1758303.html

    LCD背景知识:

    TFT(Thin Film Transistor)即薄膜场效应晶体管

    1. LCD工作的硬件需求:

       要使一块LCD正常的显示文字或图像,不仅须要LCD驱动器,并且还须要对应的LCD控制器。

    在通常情况下。生产厂商把LCD驱动器会以COF/COG的形式与LCD玻璃基板制作在一起,而LCD控制器则是由外部的电路来实现,如今非常多的MCU内部都集成了LCD控制器,如S3C2410/2440等。

    通过LCD控制器就能够产生LCD驱动器所须要的控制信号来控制STN/TFT屏了。

    也就说,LCD控制驱动器一般都是由厂家做好的。我们仅仅须要商家提供我们VBPD,VFPD。VSPW,HBPD,HFPD。HSPW,这些參数就可以。

       S3C2440LCD控制器结构图:

    http://hiphotos.baidu.com/cdgarfield/pic/item/ee38c1f30082cb947831aaec.jpg

    a:LCD控制器由REGBANK、LCDCDMA、TIMEGEN、VIDPRCS寄存器组成;

    b:REGBANK由17个可编程的寄存器组和一块256*16的调色板内存组成,它们用来配置LCD控制器的。

    c:LCDCDMA是一个专用的DMA。它能自己主动地把在侦内存中的视频数据传送到LCD驱动器。通过使用这个DMA通道,视频数据在不须要CPU的干预的情况下显示在LCD屏上。

    d:VIDPRCS接收来自LCDCDMA的数据,将数据转换为合适的数据格式,比方说4/8位单扫,4位双扫显示模式,然后通过数据portVD[23:0]传送视频数据到LCD驱动器。

    e:TIMEGEN由可编程的逻辑组成。他生成LCD驱动器须要的控制信号,比方VSYNC、HSYNC、VCLK和LEND等等。而这些控制信号又与REGBANK寄存器组中的LCDCON1/2/3/4/5的配置密切相关,通过不同的配置,TIMEGEN就能产生这些信号的不同形态。从而支持不同的LCD驱动器(即不同的STN/TFT屏)。



    3  lcd型号             我的是索尼3.5寸TFT液晶屏

    3.1 LCD液晶屏与触摸屏的区分

    首先要区分这俩个,非常多买的液晶屏都带了触摸屏,可是就仅仅有一块屏,我一開始一直没有分清楚这俩个屏,事实上这里有俩个屏,是分开的,独立的,我做触 摸屏的实验的时候我一開始就不明确这个屏亮都不亮(就是lcd没有驱动)能够驱动触摸屏吗。事实上是能够的。他们的接口是分开的。触摸屏是和AD放在一起的,主要是由于触摸屏的实现主要运用AD计算位置。

    MINI2440 索尼X36屏是TFT屏,TFT屏支持16BPp或者24Bpp(须要设置选择。例如以下图所看到的),  尺寸大小:240*320



       对于16bpp就是每一位像素16位。这样就能够用5。6,5 或者5。5。5。1 分别表示红绿蓝占的位数,后面的1就用来表示透 明度。内存布局例如以下图所看到的。


    24bpp的话就红绿蓝各占8位,这样一来使用不同的搭配就能够表示各种颜色了,内存布局如图所看到的


    ,可是对于8bpp来说使用8位,红绿蓝使用不到3位来表示,这样颜色表示的不丰富并且显示能力太弱。这样就引入了调色板。调试板事实上是一块内存。

    3.2 时序。帧频率。行频率。像素时钟


    VSYNC/VFRAME/STV:垂直同步信号(TFT)/帧同步信号(STN)/SEC TFT信号;
    HSYNC/VLINE/CPV:水平同步信号(TFT)/行同步脉冲信号(STN)/SEC TFT信号;
    VCLK/LCD_HCLK:象素时钟信号(TFT/STN)/SEC TFT信号;
    VD[23:0]:LCD像素数据输出port(TFT/STN/SEC TFT)。
    VDEN/VM/TP:数据使能信号(TFT)/LCD驱动交流偏置信号(STN)/SEC TFT 信号;
    LEND/STH:行结束信号(TFT)/SEC TFT信号;


       LCD一般须要三个时序信号:VSYNC、HSYNC和VCLK。

    VSYNC是垂直同步信号(帧同步信号),在每进行一个帧(即一个屏)的扫描之前。该信号就有效一次,由该信号能够确定LCD的场频。即每秒屏幕刷新的次数(单位Hz)。HSYNC是水平同步信号(行同步信号),在每进行一行的扫描之前,该信号就有效一次,由该信号能够确定LCD的行频。即每秒屏幕从左到右扫描一行的次数(单位Hz)。VCLK是像素时钟信号。

      s3c2440处理LCD的时钟源是HCLK,通过寄存器LCDCON1中的CLKVAL能够调整VCLK频率大小,它的公式为:

    VCLK=HCLK÷[(CLKVAL+1)×2]

    比如。HCLK的频率为100MHz,要想驱动像素时钟信号为6.4MHz的LCD屏,则通过上式计算CLKVAL值,结果CLKVAL为6.8。取整后(值为6)放入寄存器LCDCON1中对应的位置就可以。由于CLKVAL进行了取整。因此我们把取整后的值代入上式,又一次计算VCLK,得到VCLK=7.1MHz。

    VBPD。VFPD,VSPW。HBPD,HFPD,HSPW參数意义:

    VBPD(vertical back porch):表示在一帧图像開始时,垂直同步信号以后的无效的行数
    VFPD(vertical front porch):表示在一帧图像结束后,垂直同步信号曾经的无效的行数
    VSPW(vertical sync pulse width):表示垂直同步脉冲的宽度。用行数计算
    HBPD(horizontal back porch):表示从水平同步信号開始到一行的有效数据開始之间的VCLK的个数
    HFPD(horizontal front porth):表示一行的有效数据结束到下一个水平同步信号開始之间的VCLK的个数
    HSPW(horizontal sync pulse width):表示水平同步信号的宽度


       按理说,对于一个已知尺寸(即水平显示尺寸HOZVAL和垂直显示尺寸LINEVAL已知)的LCD屏,仅仅要确定了VCLK值,行频和场频就应该知道了。但这样还不行的,由于在每一帧时钟信号中,还会有一些与屏显示无关的时钟出现,这就给确定行频和场频带来了一定的复杂性。如在HSYNC信号先后会有水平同步信号前肩(HFPD)和水平同步信号后肩(HBPD)出现,在VSYNC信号先后会有垂直同步信号前肩(VFPD)和垂直同步信号后肩(VBPD)出现,在这些信号时序内,不会有有效像素信号出现,另外HSYNC和VSYNC信号有效时,其电平要保持一定的时间。它们分别叫做水平同步信号脉宽HSPW和垂直同步信号脉宽VSPW,这段时间也不能有像素信号。因此计算行频和场频时。一定要包含这些信号。HBPD、HFPD和HSPW的单位是一个VCLK的时间,而VSPW、VFPD和VBPD的单位是扫描一行所用的时间。在s3c2440中。全部的这些信号(VSPW、VFPD、VBPD、LINEVAL、HBPD、HFPD、HSPW和HOZVAL)都是实际值减1的结果。这些值是通过寄存器LCDCON2、LCDCON3和LCDCON4来配置,仅仅要把这些值配置成与所要驱动的LCD中相关内容的数据一致就可以。

    比如,我们所要显示的LCD屏大小为320×240,因此HOZVAL=320-1。LINEVAL=240-1。水平同步信号的脉宽、前肩和后肩分别为30、20和38。则HSPW=30-1。HFPD=20-1。HBPD=38-1;垂直同步信号的脉宽、前肩和后肩分别为3、12和15。则VSPW=3-1,VFPD=12-1。VBPD=15-1。

    这些參数用于配置LCD驱动控制器,由厂商设置提供;

    对于MINI2440 X35LCD屏參考參例如以下:

    VBPD =  0。VFPD =4。VSPW=8。HBPD=25,HFPD=0。HSPW=4

    寄存器配置说明:

    LCDCON1:17 - 8位CLKVAL
              6 - 5位扫描模式(对于STN屏:4位单/双扫、8位单扫)
              4 - 1位色位模式(1BPP、8BPP、16BPP等)

    LCDCON2:31 - 24位VBPD
             23 - 14位LINEVAL
             13 - 6位VFPD
              5 - 0位VSPW

    LCDCON3:25 - 19位HBPD
             18 - 8位HOZVAL
              7 - 0位HFPD

    LCDCON4: 7 - 0位HSPW

    LCDCON5:

       来源:http://blog.csdn.net/jaylondon/article/details/6363741

    举例说明:X35 LCD寄存器配置參数:

            rLCDCON1 = (6<<8) | (3<<5) |
                      (12<<1) | (0<<0);
            rLCDCON2 = (0<<24) | (319<<14) |
                      (4<<6) | (8);
            rLCDCON3 = (25<<19) | (239<<8) | (0);
            rLCDCON4 = 4;
            rLCDCON5 = (1<<11) | (1<<9) | (1<<8) | (1<<6) |
                      (0<<1)|(1);

    4.3寸屏16Bpp  480*272

    /*1.[17:8]=6  VCLK
            [7]   =0  each frame
            [6:5] =3  tft lcd panel
            [4:1]=12  16pp fot tft
        */
        rLCDCON1=(CLKVAL_TFT_320240<<8)|(0<<7)|(3<<5)|(12<<1)|0;

        /*  rLCDCON1 设置
         *     改动时间:2014/5/17
         * 设置VCLK时钟。[17:8]=6  VCLK = HCLK / [(CLKVAL + 1) × 2],此时HCLK为135M,VCLK为9M,CLKVAL = 6
         * 设置屏的类型,[6:5] =3  TFT
         * 设置bpp模式, [4:1]=12  16pp fot tft
         * 设置ENVID     [0]=0     LCD 视频输出和逻辑使能/禁止
         */
        rLCDCON1 = (6<<8)|(3<<5)|(12<<1)|0;


        /*2.[31:24]=15 (VBPD-垂直同步信号的后肩)
            [23:14]=271(272-1:行数)
            [13:6] =12  (VFPD-垂直同步信号的前肩)
            [5:0]=3  (VSPW-垂直同步信号的脉宽)
        */
        //rLCDCON2=(LTV350QV_VBPD<<24)|(LINEVAL_TFT<<14)|(LTV350QV_VFPD<<6)|(LTV350QV_VSPW);
        /*  rLCDCON2 设置
         *     改动时间:2014/5/17
         * 设置VBPD,        [31:24]=XX    VBPD(vertical back porch)表示在一帧图像開始时。垂直同步信号以后的无效的行数,垂直同步信号的后肩
         * 设置屏的LINEVAL。[23:14] =(272-1)=271  此位决定了LCD 面板的垂直尺寸(LINEVAL+1=LCD的垂直高度)LINEVAL = (垂直显示大小) - 1
         * 设置VFPD            [13:6]=XX     VFBD(vertical front porch)表示在一帧图像结束后,垂直同步信号曾经的无效的行数,垂直同步信号的前肩
         * 设置VSPW            [5:0]=XX      VSPW(vertical sync pulse width)表示垂直同步脉冲的宽度,垂直同步信号的脉宽
         */
        //rLCDCON2=(40<<24)|(271<<14)|(30<<6)|3;
          rLCDCON2 =(10<<24)|(271<<14)|(1990<<6)|3;
        /*3 [25:19]=38(HBPD-水平同步信号的后肩)
          [18:9] =479(480-1:列数)
          [7:0]  =20(HFPD-水平同步信号的前肩)
        */
        //rLCDCON3=(LTV350QV_HBPD<<19)|(HOZVAL_TFT<<8)|(LTV350QV_HFPD);
        /*  rLCDCON3 设置
         *     改动时间:2014/5/17
         * 设置HBPD,        [25:19]=XX    HBPD(horizontal back porch)表示从水平同步信号開始到一行的有效数据開始之间的VCLK的个数,水平同步信号的后肩
         * 设置屏的HOZVAL。 [18:8] =(480-1)=479  此位决定了LCD 面板的水平尺寸(HOZVAL+1=LCD的垂直高度)。HOZVAL = (水平显示大小) - 1
         * 设置HFPD            [7:0]=XX      VFBD(vertical front porch)表示在一帧图像结束后,垂直同步信号曾经的无效的行数,         垂直同步信号的前肩
         */
        rLCDCON3=(100<<19)|(479<<8)|1;
         //  rLCDCON3=(479<<8);
         /*4 [15:8]=0
          [7:0]=30(LTV350QV_HSPW:水平同步信号的脉宽)
         */
        //rLCDCON4=(MVAL<<8)|(LTV350QV_HSPW);
        /* rLCDCON4 设置
         * 设置MVAL         [15:8]=XX      STN此位定义假设MMODE 位被置位为逻辑’1’的VM 信号将要触发的频率
         * 设置HSPW         [7:0]=XX      HSPW(horizontal sync pulse width)表示水平同步信号的宽度  
         */
        rLCDCON4=15;


        /*5 [31:17] 保留0
         *  [16:15] 不须要设置。VSTATUS垂直状态(仅仅读)
         *  [14:13] 不须要设置。HSTATUS水平状态(仅仅读)
         *  [12]    此位决定24 bpp 视频存储器的顺序       1 = MSB 有效
         *  [11]    此位选择16 bpp 输出视频数据的格式    1 = 5:6:5 格式,0 = 5:5:5:1 格式    (必须选择)
         *  [10]    此位控制VCLK 有效沿的极性     1 = VCLK 上升沿取视频数据 0 = VCLK 下降沿取视频数据( 不影响)
         *  [9]        此位表明VLINE/HSYNC 脉冲极性  1 = 反转      0 = 正常       
         *  [8]        此位表明VFRAME/VSYNC 脉冲极性  1 = 反转      0 = 正常    
         *  [7]     此位表明VD(视频数据)脉冲极性  1 = 反转      0 = 正常    
         *  [6]     此位表明VDEN 信号极性     1 = 反转      0 = 正常          
         *  [5]     此位表明PWREN 信号极性     1 = 反转      0 = 正常    
         *  [4]        此位表明LEND 信号极性     1 = 反转      0 = 正常        
         *  [3]        此位表明TFT:LCD_PWREN 输出信号使能/禁止     1 = 同意     0 = 禁止        
         *  [2]        此位表明LEND 输出信号使能/禁止     1 = 同意      0 = 禁止    
         *  [1]BSWP 字节交换控制位         0 = 交换禁止 1 = 交换使能    
         *  [0]HWSWP 半字交换控制位        0 = 交换禁止 1 = 交换使能       
         */
        //rLCDCON5=(1<<11)|(1<<10)|(1<<9)|(1<<8)|(0<<6)|(BSWP<<1)|(HWSWP);
        rLCDCON5=(1<<11)|(0<<10)|(0<<9)|(0<<8)|(0<<7)|(0<<6)|(0<<5)|(1<<4)|(1<<3)|(1<<2)|(0<<1)|(1);   

    代码演示样例:


    /**************************************************************
    The initial and control for 320¡Á240 16Bpp TFT LCD----3.5´çÊúÆÁ
    **************************************************************/
    
    #include <string.h>
    #include "def.h"
    #include "2440addr.h"
    #include "2440lib.h"
    #include "LCD_LTV350QV_FOE.h"
    
    #define MVAL		(13)
    #define MVAL_USED 	(0)		//0=each frame   1=rate by MVAL
    #define INVVDEN		(1)		//0=normal       1=inverted
    #define BSWP		(0)		//Byte swap control
    #define HWSWP		(1)		//Half word swap control
    
    #define M5D(n) ((n) & 0x1fffff)	// To get lower 21bits
    
    //TFT 
    #define LCD_XSIZE_TFT 	(240)	
    #define LCD_YSIZE_TFT 	(320)
    #define SCR_XSIZE_TFT 	(240)
    #define SCR_YSIZE_TFT 	(320)
    #define HOZVAL_TFT	    (LCD_XSIZE_TFT-1)
    #define LINEVAL_TFT	(LCD_YSIZE_TFT-1)
    
    
    //FCLK=405MHz,HCLK=135MHz,VCLK=135/([6+1)*2]=9.6MHz
    #define CLKVAL_TFT_320240	(6)	
    
    
    #define LCD_BLANK		16
    #define C_UP		   ( LCD_XSIZE_TFT - LCD_BLANK*2 )
    #define C_RIGHT		   ( LCD_XSIZE_TFT - LCD_BLANK*2 )
    #define V_BLACK		   ( ( LCD_YSIZE_TFT - LCD_BLANK*4 ) / 6 )
    
    
    extern unsigned char image1[];
    extern unsigned char image2[];
    extern unsigned char image3[];
    extern unsigned char image4[];	
    extern unsigned char image5[];
    extern unsigned char image6[];	
    extern unsigned char image7[];
    volatile  static  unsigned short LCD_BUFER[SCR_YSIZE_TFT][SCR_XSIZE_TFT];
    
    #define WHITE         	 0xFFFF
    #define BLACK         	 0x0000	  
    #define BLUE         	 0x001F  
    #define BRED             0XF81F
    #define GRED 			 0XFFE0
    #define GBLUE			 0X07FF
    #define RED           	 0xF800
    #define MAGENTA       	 0xF81F
    #define GREEN         	 0x07E0
    #define CYAN          	 0x7FFF
    #define YELLOW        	 0xFFE0
    #define BROWN 			 0XBC40 //×ØÉ«
    #define BRRED 			 0XFC07 //×غìÉ«
    #define GRAY  			 0X8430 //»ÒÉ«
    
    
    /**************************************************************
    320¡Á240 16Bpp TFT LCDÊý¾ÝºÍ¿ØÖƶ˿ڳõʼ»¯
    **************************************************************/
    static void Lcd_Port_Init(void)
    {
    	/*1.2440 IOÒý½ÅÅäÖà */
    	
        rGPCUP  = 0xffffffff; //enable Pull-up register
        rGPCCON = 0xaa9556a9; //Initialize VD[7:0],LCDVF[2:0],VM,VFRAME,VLINE,VCLK,LEND 
    	
        rGPDUP  = 0xffffffff;
        rGPDCON = 0xaaaaaaaa;
    
        Uart_Printf("
    Lcd_Port_Init OK !
    ");
    }
    
    /**************************************************************
    320¡Á240 16Bpp TFT LCD¹¦ÄÜÄ£¿é³õʼ»¯
    **************************************************************/
    static void Lcd_Init(void)
    {
    	    rLCDCON1 = (6<<8) | (3<<5) | 
                      (12<<1) | (0<<0);
            rLCDCON2 = (0<<24) | (319<<14) | 
                      (4<<6) | (8);
            rLCDCON3 = (25<<19) | (239<<8) | (0);
            rLCDCON4 = 4;
            rLCDCON5 = (1<<11) | (1<<9) | (1<<8) | (1<<6) |
                      (0<<1)|(1);
    
    	rLCDSADDR1=(((U32)LCD_BUFER>>22)<<21)|M5D((U32)LCD_BUFER>>1);
    	rLCDSADDR2=M5D((U32)LCD_BUFER>>1)+240*320;
    	rLCDSADDR3=240;
    	/*  ÆÁ±ÎÖÐ¶Ï */
    	rLCDINTMSK|=(3);
    	/*  ÆÁ±ÎÖÆLPC3600/LCC3600 ģʽ*/
    	rTCONSEL = 0;
    	/*  È¡Ïûµ÷É«°å */
    	rTPAL=0;        
    }
    /*
     * ÉèÖÃÊÇ·ñÊä³öLCDµçÔ´¿ª¹ØÐźÅLCD_PWREN
     * ÊäÈë²ÎÊý£º
     *     invpwren: 0 - LCD_PWRENÓÐЧʱΪÕý³£¼«ÐÔ
     *               1 - LCD_PWRENÓÐЧʱΪ·´×ª¼«ÐÔ
     *     pwren:    0 - LCD_PWRENÊä³öÓÐЧ
     *               1 - LCD_PWRENÊä³öÎÞЧ
     */
    void Lcd_PowerEnable(int invpwren, int pwren)
    {
        rGPGCON = (rGPGCON & (~(3<<8))) | (3<<8);   // GPG4ÓÃ×÷LCD_PWREN
        rGPGUP  = (rGPGUP & (~(1<<4))) | (1<<4);    // ½ûÖ¹ÄÚ²¿ÉÏÀ­    
            
        rLCDCON5 = (rLCDCON5 & (~(1<<5))) | (invpwren<<5);  // ÉèÖÃLCD_PWRENµÄ¼«ÐÔ: Õý³£/·´×ª
        rLCDCON5 = (rLCDCON5 & (~(1<<3))) | (pwren<<3);     // ÉèÖÃÊÇ·ñÊä³öLCD_PWREN
    }    
    /**************************************************************
    LCDÊÓƵºÍ¿ØÖÆÐźÅÊä³ö»òÕßÍ£Ö¹£¬1¿ªÆôÊÓƵÊä³ö
    **************************************************************/
    static void Lcd_EnvidOnOff(int onoff)
    {
        if(onoff==1)
    	rLCDCON1|=1;                  // ENVID=ON
        else
    	rLCDCON1 =rLCDCON1 & 0x3fffe; // ENVID Off
    }
    /**************************************************************
    320¡Á240 16Bpp TFT LCDµ¥¸öÏóËصÄÏÔʾÊý¾ÝÊä³ö
    **************************************************************/
    static void PutPixel(U32 x,U32 y,U32 c)
    {
    	if ( (x < SCR_XSIZE_TFT) && (y < SCR_YSIZE_TFT) )
    	LCD_BUFER[(y)][(x)] = c;
    }
    
    /**************************************************************
    320¡Á240 16Bpp TFT LCDÈ«ÆÁÌî³äÌض¨ÑÕÉ«µ¥Ôª»òÇåÆÁ
    **************************************************************/
    static void Lcd_ClearScr(U16 c)
    {
    	unsigned int x,y ;
    		
        for( y = 0 ; y < SCR_YSIZE_TFT ; y++ )
        {
        	for( x = 0 ; x < SCR_XSIZE_TFT ; 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
    **************************************************************/
    static 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ÆÁÄ»ÉÏÓÃÑÕÉ«Ìî³äÒ»¸ö¾ØÐÎ
    **************************************************************/
    static 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);
    }
    
    /**************************************************************
    ÔÚLCDÆÁÄ»ÉÏÖ¸¶¨×ø±êµã»­Ò»¸öÖ¸¶¨´óСµÄͼƬ
    **************************************************************/
    static void Paint_Bmp(int x0,int y0,int h,int l,unsigned char bmp[])
    {
    	int x,y;
    	U32 c;
    	int p = 0;
    
        for( y = 0 ; y < l ; y++ )
        {
        	for( x = 0 ; x < h ; x++ )
        	{
        		c = bmp[p+1] | (bmp[p]<<8) ;
    			if ( ( (x0+x) < SCR_XSIZE_TFT) && ( (y0+y) < SCR_YSIZE_TFT) )
    			LCD_BUFER[y0+y][x0+x] = c ;
        		p = p + 2 ;
        	}
        }
    }
    
    /**************************************************************
    **************************************************************/
    void Lcd_Test( void )
    {
    	char ch;
    	Uart_Printf("
     GEC LCD Test
    ");
    	
    /*==========          ³õʼ»¯          		==========*/
        /* 1.LCD IO¿Ú³õʼ»¯ */
    	Lcd_Port_Init();
    	/* 2.LTV350Çý¶¯Ð¾Æ¬³õʼ»¯ */
    	LTV350QV_Power_ON();
    	/* 3.LCD ¼Ä´æÆ÷³õʼ»¯ */
    	Lcd_Init();
    	/*´ò¿ª±³¹âµçÔ´*/
    	Lcd_PowerEnable(0, 1);              
    	/* 4.LCD ¿ªÆôÊÓƵÊä³ö */
     	Lcd_EnvidOnOff(1);
        /* 5.ʹÓð×É«ÏñËØÇåÆÁ */
    
    	Lcd_ClearScr(WHITE);
    #if 0	
    	while(1)
    	{
    		Lcd_ClearScr(RED);
    		Delay(100000);
    		Lcd_ClearScr(BLUE);
    		Delay(100000);
    		Lcd_ClearScr(BLACK);
    		Delay(100000);			
    	}	
    #endif		
    	
    	
    /*==========          ´úÂë²âÊÔ          		==========*/
        /* 1.ʹÓû­Ïߺ¯Êý*/
    //	Glib_Line(1        f0,100,300,100,BLACK);
    	
    	
    	/* 2.ʹÓÃÌî³ä¾ØÐκ¯Êý*/
    //	Glib_FilledRectangle(10,100,300,200,BLUE);
    	
    	
        /* 3.ÏÔʾͼƬ*/
    //	Uart_Printf("display a beauty picture
    ");
    	Uart_Printf("display a beauty girl
    ");
    #if 0
    	while(1)
    	{
    	ch = Uart_Getch();
    	switch (ch)
    	 {
    		case 'a':
    			Paint_Bmp( 0,0,480,272, image1) ;
    			//Delay(100000);
    			break;
    		case 'b':
    			Paint_Bmp( 0,0,480,272, image2) ;
    		//	Delay(100000);
    			break;
    		case 'c':
    			Paint_Bmp( 0,0,480,272, image3) ;
    			Delay(100000);
    			break;
    		case 'd':
    			Paint_Bmp( 0,0,480,272, image4) ;
    		//	Delay(100000);
    			break;			
    	 }
    	 }
    #endif
         while( 1 )
    	 {
    	  	if(Uart_GetKey() != ESC_KEY)
    	  	{
    			Paint_Bmp( 0,0,240,320, image1) ;
    			Delay(5000000);
    		}
    		else
    		{
    			break;
    		} 
    		if(Uart_GetKey() != ESC_KEY)
    	  	{
    			Paint_Bmp( 0,0,240,320, image2) ;
    			Delay(5000000);
    		}
    		else
    		{
    			break;
    		}
    		if(Uart_GetKey() != ESC_KEY)
    	  	{
    			Paint_Bmp( 0,0,240,320, image3) ;
    			Delay(5000000);
    		}
    		else
    		{
    			break;
    		}
    		if(Uart_GetKey() != ESC_KEY)
    	  	{
    			Paint_Bmp( 0,0,240,320, image4) ;
    			Delay(5000000);
    			Lcd_ClearScr(BLACK);
    		}
    		else
    		{
    			break;
    		}
    	 }
        while(1);
    }
    //*************************************************************
    


  • 相关阅读:
    Summary for sql join in Oracle DB
    Merge data into table in Oracle
    PLSQL存储过程传出大量异常错误信息
    oracle 11g plsql解析json数据示例
    识别'低效执行'的SQL语句
    如何开启MySQL 5.7.12 的二进制日志
    Linux下ps命令详解 Linux下ps命令的详细使用方法
    Linux(Unix)时钟同步ntpd服务配置方法
    MySQL 常用命令总结
    MySQL 数据库通过日志恢复
  • 原文地址:https://www.cnblogs.com/mqxnongmin/p/10698406.html
Copyright © 2011-2022 走看看