您的位置:首页 > 编程语言

S3C2440_TFTLCD驱动程序编程要点

2011-12-20 20:34 197 查看
S3C2440 TFTLCD驱动程序编程步骤

1、打开LCD背光

将LCD背光对应的GPIO设置为禁止上拉(GPxUP相应位写入1),选择output类型(GPxCON相应位写入01),输出为高电平(GPxDAT相应位写入1)。

2、打开LCD电源

可以将GPG4选择为LCD_PWREN(GPGCON:9-8写入11),这时候LCD电源的打开/关闭可以通过LCDCON5[3]来控制。也可以自定义其他GPIO用作LCD电源开关,只需将此GPIO设置为禁止上拉(GPxUP相应位写入1),选择output类型(GPxCON相应位写入01),输出为高电平(GPxDAT相应位写入1)打开LCD电源。

3、设置其他信号线

其他信号线包括VD0-VD23和VFRAME、VLINE、VCLK等,分别在GPCCON,GPDCON中选择相应功能。

4、设置LCD的频率(VCLK)

LCD的Datasheet上一般会写有一个推荐的频率,比如我使用的屏幕推荐频率为6.4M,我需要通过一些计算选择一个合适的CLKVAL以产生这个频率:

对于TFT LCD,S3C2440提供的VCLK的计算公式为: VCLK = HCLK / ((CLKVAL+1)*2)

可以得出:CLKVAL = HCLK / (VCLK * 2) - 1

我的HCLK是49.4Mhz(CPU运行在296.4Mhz,CLKDIV_VAL设置为7, Pclk:Hclk:Fclk = 1:3:6),VCLK使用屏幕推荐的6.4M,得到:CLKVAL = 49400000 / (6400000 * 2) - 1 = 6.8

选择最接近的整数值7,写入LCDCON1[17:8]。

寄存器LCDCON1,地址0X4D000000,复位值0x00000000

Read Only

R/W

R/W

R/W

R/W

R/W

LINECNT[31:18]

CLKVAL[17:8]

MMODE[7]

PNRMODE[6:5]

BPPMODE[4:1]

ENVID[0]

MMODE: 确定VM的触发率

PNRMODE:选择屏的类型,STN或TFT

BPPMODE:选择BPP,即每个像素点多少位

ENVID: 使能/禁止LCD屏的视频(video)输出

(VCLK其实就是根据 每秒帧数*帧行数*行像素 计算出来的,帧行数和行像素需要包含空白数和同步数)

S3C2440 TFTLCD 驱动程序编程步骤

5、设置其他相关参数

LCD相关的参数主要还有这几个:

A、寄存器LCDCON2,地址0X4D000004,复位值0x00000000

R/W

R/W

R/W

R/W

VBPD [31:24]

LINEVAL [23:14]

VFPD [13:6]

VSPW [5:0]

VBPD: 帧数据结束后的空白行数(LCD屏幕的Datasheet一般有推荐值)

LINEVAL: LCD水平像素-1,如320-1 = 319

VFPD: 帧数据开始前的空白行数(LCD屏幕的Datasheet一般有推荐值)

VSPW: 帧之间垂直同步的无效行数(LCD屏幕的Datasheet一般有推荐值)

B、寄存器LCDCON3,地址0X4D000008,复位值0x00000000

R/W

R/W

R/W

HBPD(TFT)[25:19]

HFPD (TFT)[7:0]

WDLY (STN) [25:19]

HOZVAL[18:8]

LINEBLANK(STN) [7:0]

HBPD: 行结束后的VCLK时钟数(LCD屏幕的Datasheet一般有推荐值)

HOZVAL: LCD垂直像素-1,如240-1 = 239

HFPD: 行开始前的VCLK时钟数(LCD屏幕的Datasheet一般有推荐值)

C、寄存器LCDCON4,地址0X4D00000C,复位值0x00000000

R/W

R/W

HSPW(TFT)[7:0]

MVAL[15:8]

WLH(STN)[7:0]

HSPW: 行之间水平同步的无效VCLK时钟数(LCD屏幕的Datasheet一般有推荐值)

S3C2440 TFTLCD 驱动程序编程步骤

TFT 时序图

D、寄存器LCDCON5,地址0X4D000010,复位值0x00000000

Read Only

Read Only

R/W

R/W

R/W

VSTATUS[16:15]

HSTATUS[14:13]

BPP24BL[12]

FRM565[11]

NVVCLK[10]

R/W

R/W

R/W

R/W

R/W

NVVLINE[9]

INVVFRAME[8]

INVVD[7]

INVVDEN[6]

INVPWREN[5]

R/W

R/W

R/W

R/W

R/W

INVLEND[4]

PWREN[3]

ENLEND[2]

BSWP[1]

HWSWP[0]

VSTATUS: TFT屏数据状态,VSYNC、BACK Porch、ACTIVE、FRONT Porch

HSTATUS: TFT行数据状态,HSYNC、BACK Porch、ACTIVE、FRONT Porch

BPP24BL: TFT 24BPP确定Video memory存储的顺序,LSB=0、MSB=1

FRM565: TFT 16BPP选择Video memory输出数据的格式,0=5:5:5:I format、1=5:5:5

NVVCLK: STN/TFT 选择VCLK极性的激活沿,下降沿或上升沿

NVVLINE: STN/TFT 选择VLINE/HSYNC脉冲的极性,正常或反向

INVVFRAME:STN/TFT 选择VFRAME/VSYNC脉冲的极性,正常或反向

S3C2440 TFTLCD 驱动程序编程步骤

INVVD: STN/TFT 确定the VD (video data)脉冲的极性,正常或反向

INVVDEN: TFT 确定VDEN脉冲的极性,正常或反向

INVPWREN:STN/TFT 确定PWREN脉冲的极性,正常或反向

INVLEND: TFT 确定LEND脉冲的极性,正常或反向

PWREN: STN/TFT 使能/禁止LCD_PWREN输出信号

ENLEND: TFT 使能/禁止LEND输出信号

BSWP: STN/TFT 字节交换控制位

H WSWP: STN/TFT 半字交换控制位

6、设置视频缓冲区的地址

S3C2440支持虚拟屏幕,可以通过改变LCD寄存器实现屏幕快速移动

PAGEWIDTH: 虚拟屏幕一行的字节数,如果不使用虚拟屏幕,设置为实际屏幕的行字节数。若是8位为一个像素点,也就是8位为一个字,半字为4位。如宽320像素,则有320个字节数,那么按半字计算得:LCDSADDR3[10:0]=320/2。

公式:PAGEWIDTH = 屏实际宽度(半字为单位)

OFFSIZE: 虚拟屏幕左侧偏移的字节数,如果不使用虚拟屏幕,设置为0,即LCDSADDR3[21:11]=

公式:OFFSIZE = (虚拟宽度 - 实际宽度)(半字为单位)

LCDBANK: 视频帧缓冲区内存地址30-22位, 保存到LCDBANK中,即LCDSADDR1[29:21]

LCDBASEU: 视频帧缓冲区的开始地址21-1位,保存到LCDBASEU中,即LCDSADDR1[20:0]

LCDBASEL: 视频帧缓冲区的结束地址21-1位,保存到LCDBASEL中,即LCDSADDR2[20:0]

LCDBASEL = ((the frame end address) >>1) + 1

= LCDBASEU + (PAGEWIDTH+OFFSIZE) x (LINEVAL+1) // 具体看虚拟屏的框图

= 起始地址 + 缓冲区大小*字节数 // (字节为单位)

(相关寄存器LCDSADDR1,LCDSADDR2,LCDSADDR3)

举例:

#define LCDFRAMEBUFFER 0x33800000 // 虚拟屏缓冲区的起始地址

#define M5D(n) ((n) & 0x1fffff)

#define LCD_XSIZE_TFT_320240 320 // 物理屏宽

#define LCD_YSIZE_TFT_320240 240 // 物理屏高

#define SCR_XSIZE_TFT_320240 LCD_XSIZE_TFT_320240*2 // 虚拟屏宽

S3C2440 TFTLCD 驱动程序编程步骤

第 5 页 共 5 页

#define SCR_YSIZE_TFT_320240 LCD_YSIZE_TFT_320240*2 // 虚拟屏高

U32 (*frameBuffer24BitTft320240)[SCR_XSIZE_TFT_320240/1]; // 字为单位,半字为32位除以2 U32 (*frameBuffer16Bit565Tft320240)[SCR_XSIZE_TFT_320240/2];// 字为单位,半字为16位除以2 U32 (*frameBuffer16Bit555Tft320240)[SCR_XSIZE_TFT_320240/2];// 字为单位,半字为16位除以2 U32 (*frameBuffer8BitTft320240)[SCR_XSIZE_TFT_320240/4];
// 字为单位,半字为8位除以2

24BPP的TFT配置如下

// 32位为一个字,半字就为16位

frameBuffer24BitTft320240 = (U32 (*)[SCR_XSIZE_TFT_320240/1])LCDFRAMEBUFFER;

// 设置段地址,起始21位起始地址

rLCDSADDR1 = (((U32)frameBuffer24BitTft320240>>22)<<21)|M5D((U32)frameBuffer24BitTft320240>>1);

// 设置结束地址,起始地址+缓冲区大小(单位为字节),32位所以乘以4

rLCDSADDR2 = M5D(((U32)frameBuffer24BitTft320240 + (SCR_XSIZE_TFT_320240*LCD_YSIZE_TFT_320240*4))>>1 );

// OFFSIZE =(虚拟宽度-实际宽度)(单位字节),PAGEWIDTH = 屏实际宽度(单位字节),所以半字(16位) = 字节数*2

rLCDSADDR3 =(((SCR_XSIZE_TFT_320240-LCD_XSIZE_TFT_320240)*2)<<11)|(LCD_XSIZE_TFT_320240*2);

8BPP的TFT配置如下

// 8位为一个字,半字就为4位

frameBuffer8BitTft320240 = (U32 (*)[SCR_XSIZE_TFT_320240/4])LCDFRAMEBUFFER;

// 设置段地址,起始21位起始地址

rLCDSADDR1 = (((U32) frameBuffer8BitTft320240 >>22)<<21)|M5D((U32) frameBuffer8BitTft320240 >>1);

// 设置结束地址,起始地址+缓冲区大小(单位为字节),8位所以乘以1

rLCDSADDR2 = M5D(((U32) frameBuffer8BitTft320240 + (SCR_XSIZE_TFT_320240*LCD_YSIZE_TFT_320240*1))>>1 );

// OFFSIZE =(虚拟宽度-实际宽度)(单位字节),PAGEWIDTH = 屏实际宽度(单位字节),所以半字(4位) = 字节数/2

rLCDSADDR3 = (((SCR_XSIZE_TFT_320240-LCD_XSIZE_TFT_320240)/2)<<11)|(LCD_XSIZE_TFT_320240/2);

7、确定信号的极性

2440的LCD控制器允许设置VCLK、VLINE、VFRAME等信号的极性(上升沿有效还是下降沿有效),需要对照LCD的Datasheet一一确认。(相关寄存器LCDCON5)

8、禁止LPC3600/LCC3600模式!

如果不是使用三星LPC3600/LCC3600LCD,必须禁止LPC3600/LCC3600模式(写入0到TCONSEL)!

9、屏蔽LCD中断:rLCDINTMSK |= (3);

10、禁止临时调色板:rTPAL = 0;

11、打开视频输出:ENVID设为1 (LCDCON1:0写入1)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: