1-16 LCD的原理与应用

时间:2022-07-05 09:24:00

(详细的实验代码,在这里:https://github.com/elvinsys/arm_tq2440/tree/master/1_uboot/1-16.lcd

一、  LCD的工作原理解析

    1.  LCD硬件体系结构

1-16 LCD的原理与应用

        1.1  液晶的概念

            属于一种有机化合物,分子形态为长棒状,在不同的电流作用下,分子会做有规律的旋转,对光线产生一定的控制形成一个像素,而多个像素构成完整的图像。

        1.2  分类:STN、GF、TFD、还有常用的TFT

        1.3  LCD驱动芯片

            是用来控制液晶分子发生变化的模块,它为液晶分子的偏转提供电压。

        1.4  LCD控制器(参考2440芯片手册中的LCD Controller一节  图15-1)

            为LCD驱动芯片提供必需的数据和控制信号

            LCD            数据、控制、时钟                 LCD

            控制器————————————>    驱动芯片

        REGBANK包括:17个   R/W    REGISTER

                                        256 X 16  的调色板内存

        LCDCDMA:把帧内存的视频数据传送到LCD驱动器的专用DMA通道

        VIDPRCS:接受来自LCDCDMA的数据,将数据转换格式。(如4/8位单扫或4位双扫显示)

        TIMEGEN:生成LCD控制信号,如:VSYNC、HSYNC、VCLK和LEND等信号

    

    2.  LCD显示与信号

        2.1  显示流程

            2.1.1  从第一行第一个点,到第一行最后一个点

            2.1.2  显示指针回到下一行第一个点的时间称为切换时间

            2.1.3  显示完一副图像,一帧显示完成

        2.2  时序信号(参考15-6,TFT LCD Timing Example)

VSYNC
垂直同步信号
HSYNC 水平同步信号
VCLK 像素时钟信号
VD[23:0] LCD像素数据输出端口
VDEN 数据使能信号
LEND 行结束信号


二、  基于S3C2440的LCD驱动程序设计

大概的步骤如下:

1.  LCD初始化

    1.1  引脚初始化

    1.2  时序初始化

    1.3  帧缓冲初始化

    1.4  杂项初始化

2.  LCD图像显示

    2.1  数据显示

    2.2  单色显示


    1.LCD初始化

        1.1  引脚初始化(touch lcd.c,记得把lcd.o丢进dev/Makefile里面)

            (查看原理图可知,LCD的VD0~VD23分别对应GPC8-GPC15,GPD0-GPD15),因此配置一下寄存器:

            GPCCON    R/W    0x5600 0020    ——>    0xaaaa aaaa

            GPDCON    R/W    0x5600 0030    ——>    0xaaaa aaaa

            创建函数——void lcd_port_init();

       1.2  时序初始化

            查看原理图,参考15-6图可知,需要被初始化的时序信号如下:

VSPW HSPW CLKVAL
VFPD HFPD LINEVAL
VBPD HBPD HOZVAL

上面信号的寄存器位置如下,创建函数——void lcd_control_init();

LCDCON1 R/W 0x4d00 0000
CLKVAL [17:8]  
LCDCON2 R/W 0x4d00 0004
VBPD [31:24]  
LINEVAL [23:14]  
VFPD [13:6]  
VSPW [5:0]  
LCDCON3 R/W 0x4d00 0008
HBPD [25:19]  
HOZVAL [18:8]  
HFPD [7:0]  
LCDCON4 R/W 0x4d00 000c
HSPW [7:0]  
   

按照时序信号的值,计算出需要初始化寄存器的值(参考4.3寸屏手册中7.1表和2440手册LCDCON0)

DCLK = VCLK = HCLK / [ ( CLKVAL +1 ) X 2 ] = 10

HCLK = 100, 故 CLKVAL = 4

(参考2440的4.3寸屏手册和15-6图)

VSPW +1 =10 故    VSPW = 9

VBPD +1 = 2   故    VBPD = 1

VFPD +1 = 2   故    VFPD = 1

HSPW + 1 = 41 故    HSPW = 40

HBPD + 1 = 2   故   HBPD = 1

HFPD +1 = 2    故    HFPD = 1

LINEVAL + 1 = 272  故  LINEVAL = 271

HOZVAL +1 = 480   故   HOZVAL = 479


        1.3  帧缓冲初始化 (272行 X 480列) X 2字节

unsigned short LCDBUFFER[272][480];

typedef unsigned int U32;

typedef unsigned short U16;

typedef unsigned char U8;

        把LCD帧缓冲区地址填装进LCD Controller里面

LCDSADDR1        R/W        0x4d00 0014

LCDBANK        [29:21]   :放BUFFER地址的[30:22]

LCDBASEU     [20:0]      :放地址的[21:1]

具体代码为:LCDSADDR1 = (((U32)LCDBUFFER>>22)<<21) | (((U32)LCDBUFFER>>1)&0x1fffff);


LCDSADDR2        R/W        0x4d00 0018

LCDBASEL        [20:0]   :因为是single scan LCD,故存放的是结束地址[21:1]

具体代码为:LCDSADDR2 = (((U32)LCDBUFFER + 272 * 480 *2) >> 1) &0x1fffff;


LCDSADDR3        R/W        0x4d00 001c

OFFSIZE            [21:11]   :两个像素点的距离为0

PAGEWIDTH     [10:0]      :半字页宽为480 *2 / 2

具体代码为:LCDSADDR3 = (0 << 11) | (480 * 2 / 2 );


        1.4  杂项初始化

LCDCON1    

PNRMODE    [6:5]    :    1    =    TFT LCD

BPPMODE     [4:1]    :    1100  = 16 BPP TFT

ENVID            [0]           :     0   =   Disable LCD    (关闭LCD Controller)


LCDCON5        R/W        0x4d00 0010

FRM565         [11]        :    1    =    5    :    6    :    5    format   (RGB)

INVVLINE       [9]          :    1    =    lnverted    //极性相反

INVVD             [8]          :    1    =    lnverted    //极性相反

HWSWP         [0]          :    1    =    Swap Enable    半字转换


TPAL           R/W        0x4d00 0050    临时调色板

TPALEN          [24]       :      0    =    DISABLE    //暂时关闭

直接TPAL  =  0


        1.5  建立函数——void led_init(), 并添加到main.c中

            1.5.1  把lcd_port_init() 和 lcd_control_init()  加到main.c里面

            1.5.2  打开LCD 电源:LCD_PWR : GPG4

                  GPGON    R/W    0x5600 0060

                  GPG4        [9:8]    :   11    =    LCD_PWRDN

                  LCDCON5    R/W

                  PWREN    [3]       :    1     =    ENABLE PWREN

                  LCDCON1    R/W

                  ENVID       [0]       :     1    =    ENABLE OUTPUT


    2.  LCD图形显示

        2.1  数据显示

            建立——void point(U32 x, U32 y, U32 color)   用来画一个点(参考2440手册15-18:VD Pin D at 16BPP 5:6:5)提取red、green、blue,具体代码如下:

void print_point(U32 x, U32 y, U32 color)
{
U32 red, green, blue;
red   = ((color>>19)&0x1f);
green = ((color>>10)&0x3f);
blue  = ((color>>3)&0x1f);
LCDBUFFER[y][x] = (unsigned short)((red<<11)|(green<<5)|(blue<<0));
}

            建立测试函数——void lcd_test();   用来画一行线

void print_line(U32 y, U32 color)
{
int i;
for(i=0;i<480;i++)
print_point(i,y,color);
}

            在LCD上显示一张图的函数:

void print_picture(U16 x0, U16 y0, U16 wide, U16 high, const U8 *bmp)
{
U16 x, y, c;
U32 p = 0;
for(y = y0; y < y0+high; y++)
{
for (x = x0; x < x0+wide; x++)
{
c = (bmp[p] | (bmp[p+1]<<8));
if((x<480)&&(y<272))
LCDBUFFER[y][x] = c;
p = p + 2;
}
}
}

/*  把一张位图转换成一个bmp.c的数组文件,可利用工具Img2Lcd进行转换,

把bmp.c丢在dev目录下,修改Makefile,把bmp.c中的数组名修改为bmp,

在lcd.c中加入extern unsigned char bmp[90200],在lcd_test中加入Paint_Bmp(0,0,220,220,bmp);

        2.2  单色显示(利用临时调色板)

TPAL        R/W        0x4d00 0050

TPALEN    [24]    1    :    ENABLE    //启动调色板

TPALVAL    [23:0]

                    [23:16 ]    red

                    [15:8 ]    green

                    [7:0 ]    blue

具体代码如下:

void clearSrc(U32 color)
{
TPAL = (1<<24)|(color&0xffffff);
}