裸机LCD驱动设置

参考:http://www.cnblogs.com/lifexy/p/7144890.html


横屏4.3寸LCD为480*272(一行:480个像素点    一列:272个行)

1、1.1  LCD原理图:

Pin1-Pin6:Von/Voff    电源正/负(由GPG4控制,高电平要效)

Pin2:VM、VDEM 数据使能信号(0:表示正在跳行,1:表示可以传输像素数据)

Pin8:VLINE/HSYNC 水平同步信号(每扫完一行,即发一次水平同步信号)

Pin28:VFRAME/VSNC 垂直同步信号(每扫完一屏,即发一次垂直同步信号)

Pin30:VCLK 始终信号

Pin42,Pin45 LED+,LED- 背光显示开关(由0:off    1:no)

VD23~VD19:R信号

VD15~VD10:G信号

VD7~VD3    :B信号


KEYBOARD:背光电路


LCD PWREN:LCD电源

只有LCD电源和LCD背光电路接通后,LCD才会亮起来。

数据是采用16Bpp像素,RGB565格式(因为LCD控制器不支持18Bpp格式)


1.2 配置引脚

//参考以前的裸机程序lcddrv.c
    *gpccon  = 0xaaaaaaaa;   /* GPIO管脚用于VD[7:0],LCDVF[2:0],VM,VFRAME,VLINE,VCLK,LEND */
	*gpdcon  = 0xaaaaaaaa;   /* GPIO管脚用于VD[23:8] */

	*gpbcon &= ~(3);	/* GPB0(KEYBOARD)设置为输出引脚 */
	*gpbcon |= 1;
	*gpbdat &= ~1;	/* 输出低电平,背光先不开启 */

	*gpgcon |= (3<<8);	/* GPG4用作LCD_PWREN */


2、 设置LCDCON1~5控制器

2.1 BSWP和HWSWP介绍

更改存储格式,对于16BppRGB565(高数据在后)来说,BSWP=0,HWSWP=1


2.2 查看2440中LCD控制器初始状态时序图


VSPW:垂直同步脉冲宽度 pulse width

VBPW:垂直脉冲后延延迟(用来等待LCD模块响应的时间)back delay

VFPD:垂直脉冲前沿延迟(用来等待LCD模块响应的时间)Front delay

HSPW:行同步脉冲宽度pulse width

HBPD:行脉冲后沿延迟(用来等待LCD模块响应的时间)back delay

HFPD:行脉冲前沿延迟(用来等待LCD模块响应的时间)Front delay

LINEVAL:行数,用来决定垂直尺寸,对于4.3寸,LINEWAI=272-1

HOZVAL:行数,用来决定水平像素点个数,对于4.3寸时,HOZVAL=480-1

2.3 查看LCD芯片手册时时序图,计算周期时间:


从上图1中可以得到时钟周期(Clock cycle)为9MHz。

从LCD控制器初始状态时序图、图1和图2计算出:(LCD控制器初始状态时序图 和 图2对应着来看)

垂直方向:

tvb=2,VBPD+1=tvb,VBPD=1

tvd=272,LINEVAL+1=tvd,LINEVAL=271

tvf=2,VFPD+1=tvf,VFPD=1

tvp=10,VSPW+1=TVP,VSPW=9

水平方向:

thb=2,HBPD+1=thb,HBPD=1

thd=480,HOZVAL+1=thd,HOZVAL=479

thf=2,HFPD+1=thf,HFPD=1

thp=41,HSPW+1=thp,HSPW=40


设置LCDCON1寄存器:

CLKVAL[17:8]:

设置VCLK时钟,TFT,CLKVAL=HCLK/(LCD时钟*2)-1

本裸板的HCLK=100Mhz,LCD时钟为9MHZ,所以CLKVAL=4

PNRMODE[6:5]:

设置为TFT模式,PNRMODE = 0x3

BPPMODE[4:1]:

设置为16BPP,BPPMODE=0x0C

ENVID[0]:

控制PWREN信号(GPF4)输出,先配置好再输出PWREN,ENVID=0

(开启之前应该设置LCDCON5位[3]允许PWREN信号才有效)

设置LCDCON2寄存器:

VBPD[32:24]:垂直脉冲后沿延时,VBPD=1

LINEVAL[23:14]:垂直行数,决定垂直大小,LINEVAL=271

VFPD[13:6]:垂直脉冲前沿延时,VFPD=1

VSPW[5:0]:垂直同步脉冲宽度,VSPW=9

设置LCDCON3寄存器:

HBPD[25:19]:水平脉冲后沿延时,HBPD=1

HOZVAL[18:8]:水平像素点个数,HOZVAL=479

HFPD[7:0]:水平脉冲前沿延时,HFPD=1

设置LCDCON4寄存器:

HSPW[7:0]:水平同步脉冲宽度,HSPW=40

设置LCDCON5寄存器:

FRM565[11]:设置16bpp输出模式,FRAM565=1(RGB565);

INVVCLK[10]:设置VCLK极性,我们可以看时序图的VD和相对应的VSYNC,所以等于0,下降沿读取

INVVLINE[9]:HSYNC水平同步信号反转,因为LCD手册和2440手册不一样,所以INVVLINE=1;

INVVFRAME[8]:VSYNC垂直同步信号反转,因为LCD手册和2440手册不一样,所以INVVFRAME=1;

PWREN[3]:PWREN信号(GPG4)允许文,=0,不设置,等设置了缓存寄存器后才设置

HWSWP[0]:更改存储格式,这里HWSWP=1,BSWP等于0,使我们的LCD像素显示从低到高排列

上述代码如下:

lcd_regs->lcdcon1 = (4<<8) | (3<<5) | (0x0c<<1); 
lcd_regs->lcdcon2 = (1<<24) | (271<<14) | (1<<6) | (9);
lcd_regs->lcdcon3 = (1<<19) | (479<<8) | (1);
lcd_regs->lcdcon4 = 40;
lcd_regs->lcdcon5 = (1<<11) | (0<<10) | (1<<9) | (1<<8) | (1<<0);


3、设置LCDSADDR1~3缓冲地址寄存器

设置LCDSADDR1寄存器:

LCDBANK[29:21]:

保存缓冲起始地址A[30:22]

LCDBASEU[20:0]:

保存缓冲起始地址A[21:1]

(第0位和最高位被忽略了。。)

设置LCDSADDR2寄存器:

LCDBASEL[20:0]:保存缓冲结束地址A[21:1],这里我们采用4.3寸LCD,所以等于

((s3c_lcd->fix.smem_start + s3c_lcd->fix.smem_len) >> 1) & 0x1fffff; //结束地址=开始地址+长度,只关心21位

设置LCDSADDR3寄存器:

OFFSIZE[21:11]:

保存LCD上一行结尾和下一行开头的地址之间的差(半字数为单位),我们使用的是连续地址,所以不设置,默认为0

PAGEWIDTH[10:0]:

保存LCD一行占的宽度(半字数为单位),我们每个像素点是半字数,所以等于480。

代码如下:

lcd_regs->lcdsaddr1 = (s3c_lcd->fix.smem_start >> 1) & ~(3<<30);	//第0位和最高位忽略
lcd_regs->lcdsaddr2 = ((s3c_lcd->fix.smem_start + s3c_lcd->fix.smem_len) >> 1) & 0x1fffff;	//结束地址=开始地址+长度,只关心21位
lcd_regs->lcdsaddr3 = (480*16/16);	/* 一行的长度(单位:半字,就是2个字节) */


4、 启动LCD,并使能背光灯

        /* 启动LCD */
	lcd_regs->lcdcon1 |= (1<<0);	/* 使能LCD控制器 */
	lcd_regs->lcdcon5 |= (1<<3);	/* 使能LCD本身 */
	*gpbdat |= 1;	/* 原来输出低电平,现在输出高电平,使能背光灯 */

猜你喜欢

转载自blog.csdn.net/xiaodingqq/article/details/80724190