mini2440裸机之LCD


1、LCD控制器

      打开S3C2440数据手册可以看到LCD控制器硬件组成框图如下



2、LCD时序图

        对此图做简单描述:LCD控制器主要由REGBANK,LCDCDMA,VIDPRCS,TIMEGEN等寄存器组成,如果不是用的三星的LCD,LPC3600和LCC3600就不用管它,它们专门为三星的LCD设计的。

        REGBANK由17个可编程的寄存器和一个256X16调色板内存组成,他们用来配置LCD控制器

        LCDCDMA是一个专用的DMA,它能自动将帧内存中的数据传送到LCD驱动器,通过这个DMA通道,数据不需要CPU干涉就能传送到LCD上显示。

        VIDPRCS接收来自LCDCDMA的数据,并转换成合适的数据格式再送到LCD驱动器中。

        TIMEGEN由可编程的逻辑组成,生成LCD驱动器的控制信号。

        我们在LCD上显示的一幅图像称为一帧图像。在LCD上显示一帧图像的原理:从第一行的最左边开始扫描,一行结束后跳到下一行继续扫描。当显示完一幅图像后,从新

        第一行接着扫描。扫描的时候就像一个“Z”字形。扫描图像必须在控制信号下进行,下面讲解一下控制信号。在mini2440开发板上用的是W35的TFT屏。TFT屏工作时序如下图所示

对上面对参数解释一下

VSYNC:垂直同步信号

VSPW:表示垂直同步脉冲的宽度,用行数计算

VBPD:表示新一帧图像的开始,垂直同步信号以后无效的行数

VFPD:表示新一帧图像结束后,垂直同步信号以前的无效的行数

HSYNC:水平同步信号,表示新的一行的开始,即跳到最左边开始行的一行数据的扫描。

HSPW:表示水平同步信号的宽度,用VCLK计算

HBPD:表示水平同步信号从开始到一行的有效数据开始之间VCLK的个数

HFPD:表示一行有限数据结束到下一个水平同步信号开始之间VCLK的个数

VCLK:像素时钟信号

VD[23:0]:LCD像素数据输出端口

VDEN:数据使能信号

LEDN:行结束信号

       显示图像的时候会看到图像四周有黑色边框,结合时序图解释一下:当我们发出VSYNC信号后,要经过(VSPW+1+VBPD+1)这么长时间,那么这么长时间所扫面的行是无效的,这对应着我们图像的最上边的黑框,接下来是扫描LINEVAL+1行有效数据,最后经过(VFPD+1)个无效行,这对应着图像下面的黑框。对于每一行图像数据,HSYNC信号发出后,经过(HSPW+1+HBPD+1)个无效像素,这对应着我们图像左边黑框,接下来显示HOZVAL+1个有效像素,接着扫描(HFPD+1)个无效像素,这对应着我们图像的右边黑框。

        VSYNC信号的出现表示一帧图像的开始,我们把1s内能显示图像的帧数称为显示器频率,也叫做场频率或者垂直频率。显示分辨率又称屏幕分辨率,指显示器屏幕上显示的有效像素点的数目。这是不同的概念。

 3、LCD操作

         下面讲解如何操作LCD来显一帧图像:

         一个像素点的颜色是由三种颜色(红,绿,蓝)按照一定比例配置得到的,每种颜色由几位二进制来表示,到底是由几位来表示需要我们设置LCD寄存器来配置。LCD支持单色(1BPP),4级灰度(2BPP),16级灰度(4BPP),256级灰度(8BPP)调色板显示模式和16BPP和24BPP的非调色板显示模式。BPP:bit   per   Pixel   即  位/像素。  我们的LCD就是选择的16BPP显示模式,16BPP有两种表示方式,分别为5:5:5:1显示模式和5:6:5显示模式。我的LCD选择的是5:6:5显示模式,5:6:5表示的就是前5位二进制表示的事红色,中间6位表示绿色,最后5位表示的是蓝色。16BPP显示模式图如下所示



         我们先了解下有关帧内存的概念,所谓的帧内存就是图像数据的存放地址,我们将图像数据放入到帧内存中,然后自动通过LCDDMA将数据送到LCD上显示。

         我们主要要对一下几个寄存器进行操作:LCDCON1,LCDCON2,LCDCON3,LCDCON4,LCDCON5,LCDSADDR1,LCDSADDR2,LCDSADDR3

         LCDCON1寄存器如下图所示


          第0位是LCD信号输出使能位,[4:1]位是选择BBP模式,[6:5]位是选择显示模式,我们LCD是TFT屏,故此处应该设置为3,[7]用不到暂时不管,[17:8]位用来设置像素信号始终,这个要根据具体的LCD数据手册来设置,[27:18]没用到暂时不管。

         LCDCON2寄存器如下图所示 


       此处的各参数的含义前面已经解释过了,我们需要查看LCD的数据手册进行设置,其中LINEVAL设置为239,因为我们LCD是320X240的屏

       LCDCON3寄存器如下图所示


     参考数据手册对上图进行配置,其中HOZVAL为319

     LCDCON4寄存器如下图所示


    我们只需用到[7:0]位参考数据手册对HSPW进行设置

    LCDCON5寄存器如下图所示



第0、1位用来设置数据存储方式,我们ARM上电默认的方式是小端模式,即数据的低位放在低地址处,数据的高位放在高地址处。第3位用来设置给LCD供电,我们LCD有两种供电方式,一种是外接电源,一种是我们io口输出高电平供电,mini2440采用的是io口供电,采用IO供电的好处是当我们不用LCD的时候可以通过软件来设置LCD的开启与关闭。第8、9位是设置信号极性的。所谓信号极性入下图所示


上面一个波形是正极性,下面一个为负极性。参考我们的LCD时序图可以看出,我们在时钟信号的下降沿采集数据,故应该设置为负极性信号,第10位设置为1。第11位用来设置显示模式,我们采用的的是5:6:5模式。谈到数据存储,我们接下来讲一讲帧内存的概念,所谓帧内存就是图像数据在内存中的存储地址,我们将数据存放在帧内存中,然后将帧内存的地址告诉LCD控制器,LCD会自动通过DMA读取数据并显示。因此,我们在编程的时候应该事先声明一个数组用来保存图像数据,然后将内存地址告诉LCd控制器。

下面介绍一下帧内存地址寄存器


【29:21】位用来保存帧内存地址的高9位【30:22】,【20:0】用来保存LCD的帧缓冲区开始地址的【21:1】位


用来保存LCD的帧缓冲区的结束地址的【21:1】位。它的计算方法应经给出来了,LCDBASEL=((the frame end address)>>1)+1=LCDBASEU+(PAGEWID+OFFSIZE)x(LINEVAL+1)


我们用到【10:0】位,这里用来设置视口的宽度,半字位单位,我们一个像素就是半字,LCD的宽度为320个像素,故应该设置为320,其他位置0即可。

下面给出几个例子

1、我们在LCD上显示一个蓝色的点。程序如下:

#include "2440addr.h"

//根据数据手册设置配置参数,W35的屏的收据手册可能参数上有点老了,反正我按照上面的配置就是不对,然后参照开发板自带的程序进行配置
//LCDCON1配置
#define CLKVAL 4
#define BPPMODE 12
#define PNRMODE 3

//LCDCON2配置
#define HEIGHT 240
#define VBPD 10
#define VFPD 4
#define VSPW 1

//LCDCON3,4配置
#define WIDTH 320
#define HBPD 0x44
#define HFPD 0x04
#define HSPW 0x01

//LCDCON5配置
#define FRM565	1
#define INVVCLK 1
#define INVLINE 1
#define INVVFRAME 1
#define PWREN 1
#define BSWP 0
#define HWSWP 1

//此宏定义就是为了获取LCD的帧缓冲区的起始地址的【21:1】位
#define Low21Bits(n)	((n)&0x1fffff)

//声明一个帧内存用于保存帧图像数据
volatile unsigned short Lcd_Buffer[240][320];

//LCD控制寄存器初始化
void Lcd_Init(void)
{
	rGPCCON=0xaaaa02a9;
	rGPDCON=0xaaaaaaaa;  //先将GPC和GPD的管教配置为LCD下的功能。
	
	rLCDCON1=(CLKVAL<<8)|(PNRMODE<<5)|(BPPMODE<<1);
	rLCDCON2=(VBPD<<24)|((HEIGHT-1)<<14)|(VFPD<<6)|(VSPW);
	rLCDCON3=(HBPD<<19)|((WIDTH-1)<<8)|(HFPD);
	rLCDCON4=HSPW;
	rLCDCON5=(FRM565<<11)|(INVVCLK<<10)|(INVLINE<<9)|(INVVFRAME<<8)|(BSWP<<1)|(HWSWP);
	
	rLCDSADDR1=(((unsigned int)Lcd_Buffer>>22)<<21)|Low21Bits((unsigned int)Lcd_Buffer>>1);
	rLCDSADDR2=Low21Bits(((unsigned int)Lcd_Buffer+(240*320*2))>>1);
	rLCDSADDR3=(0<<11)|(WIDTH);
}

void Lcd_PowerEnable(int powerEnable)
{
    rGPGCON&=~(3<<8)|(2<<8);
    rGPGDAT|=1<<4;
    rLCDCON5&=~(1<<3)|(powerEnable<<3);
}


void PutPixel(unsigned int x,unsigned int y,unsigned short c)
{
    if((x<320)&&(y<240))
        Lcd_Buffer[y][x]=c;
}


void Lcd_ClearScr(unsigned int c)
{
    unsigned int x,y;
    for(y=0;y<240;y++)
    {
        for(x=0;x<320;x++)
        {
            Lcd_Buffer[y][x]=c;
        }
    }
}

int Main()
{
    Lcd_Init();
    Lcd_PowerEnable(1);
    rLCDCON1|=1<<0;
    Lcd_ClearScr(0xffff);
    while(1)
    {
        PutPixel(100,100,569);
    }
    return 0;
} 




  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值