一、LCD简介
LCD-liquid crystal display 的简称,液晶显示器按驱动方式分为1.静态驱动、2.简单矩阵驱动及3.主动矩阵驱动。
其中,简单矩阵又可分为1.扭转向列型(TN)和超转向列型(STN)两种,而主动矩阵驱动则以TFT为主。
TN与STN都采用场电压驱动方式,如果显示尺寸加大,中心部分对电机变化的反应时间就会变长,显示器的速度跟不上。为解决这个问题,主动矩阵驱动TFT被提出,他通过晶体管显示信号开启过关闭液晶分子的电压,从而避免了显示器对电场效应的依靠。
1.1LCD常见参数:
- 像素 :LCD屏上所能控制最小单位
- 分辨率:LCD屏像素总数,一般采用“横向像素点x纵向像素点”,如320*240或640*480
- 位像素BPP:指某一分辨率下,每个像素点可以用多少bit来表示该点颜色。例如:16bpp表示用16bit表示像素点色彩,色彩范围是0--2^16。位像素与分辨率乘积决定显存大小。
- 刷新率:图像在屏幕上更新速度
- 物理尺寸:LCD外观对角线长度,单位为英寸。如3.5英寸、4.3英寸
1.2 LCD显示系统
S3C2440A 的LCD 控制器简介
S3C2440A 中的LCD 控制器由从位于系统存储器的视频缓冲区到外部LCD 驱动器的转移LCD 图像数据逻辑组成。LCD 控制器支持单色LCD 的单色、2 位每像素(4 阶灰度)或4 位每像素(16 阶灰度)模式,通过使用基于时间的抖动算法和帧频控制(FRC)方法,其可以连接到8 位每像素(256 色)的彩色LCD 面板和连接到12 位每像素(4096 色)的STN LCD。可以编程LCD 控制器来支持不同涉及屏幕水平和垂直像素数、数据接口的数据线宽度、接口时序和刷新率的需要。
特性
STN LCD 显示:
– 支持3 种类型的LCD 面板:4 位双扫描、4 位单扫描和8 位单扫描显示类型
– 支持单色、4 阶灰度和16 阶灰度
– 支持256 色和4096 色的彩色STN LCD 面板
– 支持多种屏幕尺寸
典型实际屏幕尺寸:640×480、320×240、160×160 等
最大虚拟屏幕尺寸为4M 字节
256 色模式最大虚拟屏幕尺寸:4096×1024、2048×2048、1024×4096 等
TFT LCD 显示:
– 支持TFT 的1、2、4、8 bpp(位每像素)调色显示
– 支持彩色TFT 的16、24 bpp 无调色显示
– 支持24 位每像素模式下最大16M 色TFT
– 支持多种屏幕尺寸
典型实际屏幕尺寸:640×480、320×240、160×160 等
最大虚拟屏幕尺寸为4M 字节
64K 色模式最大虚拟屏幕尺寸: 2048×1024 等
由SDRAM、CPU(S3C2440)、LCD驱动器、TFT型LCD共4部分组成。不管什么架构CPU,LCD显示系统组成都不会变化。一般LCD驱动器与LCD屏集成在一起。
LCD系统结构
工作原理:
1、 将需要显示的图像存放在显示缓存中。S3C2440通过地址线和数据线实现对显存读取和存放。
嵌入式中没有专门的显存芯片,而是将S3C2440的内存SDRAM划出4Mbyte空间作为显示缓存。
2、 LCD控制器通过数据线、控制线、时钟线将显示数据,传送给LCD驱动器。
LCD控制器集成在S3C2440(编写LCD驱动实质就是操作LCD控制器)
3、 LCD驱动器将信号处理后,直接驱动TFT显示
注:
1、显存大小如何确定?显存大小=图形分辨率×位像素/8,TX2440使用东华LCD:若使用位像素为16,图形分辨率320*240,则16*320*240/8=150KB,则显存大于150KB即可。需要验证一下??
验证:通过计算程序中显存终止地址-起始地址=显存大小
rLCDSADDR1(寄存器地址0x4d000014)----设置显存的起始地址(寄存器[20:0]对应起始地址[21:1])
rLCDSADDR2(寄存器地址0x4d000018)----设置显存的终止地址(寄存器[20:0]对应终止地址[21:1])
程序中显示的帧缓冲区起始地址、结束地址定义
rLCDSADDR1=(((U32)LCD_BUFFER>>22)<<21)|M5D((U32)LCD_BUFFER>>1)
rLCDSADDR2=M5D( ((U32)LCD_BUFFER+(SCR_XSIZE_TFT*LCD_YSIZE_TFT*2))>>1 );
其中:LCD_BUFFER---定义存放显示图像的数组unsigned short LCD_BUFFER[240][320],占用空间=240*320*2byte=150KB(unsigned short 占用2个byte)
显存大小=(终止地址-起始地址)*2=(4EBC2-3BFC2)*2=12C00*2=75KB*2=150KB 此处为什么乘以2,因为计算地址时,做了左移一位。
AXD调试时内存数据
经过上面验证可知:S3C2440的LCD控制器提供4Mbyte帧缓冲区(即LCD结构图中显存),而3.5寸的320*240LCD使用了150KB。
2、编写LCD驱动实质就是操作LCD控制器,下面重点讲解一下LCD控制器。
LCD控制器框架
由上图LCD控制框架可知:
由寄存器组REGBANK+定时器产生器TIMEGEN+视频多路开关VIDEOMUX+LPC3600(适用三星TFT屏)+LCD专用DMA LCDDMA+VIDPRCS构成,作用是:传送视屏数据以及产生需要的控制信号VFAME、VLIN 、VCLK、VM等。LCD控制器使用VD[23:0]传送图像数据到LCD驱动器。
- REGBANK是17个寄存器组和调色板组成,作用是配置LCD控制器。重点
- 定时器产生器TIMEGEN作用:支持不同LCD驱动器接口时序图,产生VFAME、VLIN 、VCLK、VM等信号。
- LCDDMA是专用DMA,自动地传送显存中像素数据,通过VD[23:0]传送到LCD驱动器。在此过程中,视屏数据不需要CPU干预,就能显示到LCD屏上。
- VIDPRCS作用调整从LCDDMA接收图像数据格式,然后VD[23:0]传送到LCD驱动器。
- LPC3600是专门适用三星TFT屏,TX2440使用东华LCD,所以不需要设置。
1.3 数据格式
下面以显示模式设定为TFT的16bpp为例,说明一下。由下图可知:
1、例如像P1每个像素点由16bit表示,占用视屏缓冲区2个字节(即地址000H--001H)
2、设置16bpp输出格式为5:5:1。即数据A[31:16]表示像素点1,而数据[15:0]表示像素点2。
3、图3中表示16BPP的数据在VD[23:0]传输格式。输出格式5:5:I等同5:5:1。
图1:16BPP在缓冲区存储数据格式 图2:16BPP输出视频数据格式
图3:16BPP下VD引脚描述
1.4虚拟屏、视口概念
S3C2440支持4MB的虚拟屏幕,就是指显示图像的大小最大可达4MB。4MB的图像,即使使用24bpp的模式也是一个比较大的图片(1024×1024)。为了更好的使用这个特性S3C2440对于图像数据的读取处理给出了一个直观的图像,这个图像中,可以看到屏幕可以当成一个“视口”在这个4MB的图像区域“滑动”。这个视口可大可小,但是这个一般由你的设备的屏幕决定(TX2440的屏幕为3.5寸,大小为320×240)。
S3C2440A 支持硬件水平或垂直滚屏。要实现滚屏,需要改变LCDSADDR1/2 寄存器中LCDBASEU 和LCDBASEL 的字段,删除PAGEWIDTH 和OFFSIZE 的值。 实现前提:储存在视频缓冲器中的图像应该在尺寸上大于LCD 面板屏幕 。 未测试过
上面表示虚拟屏幕的地址空间必须4MB对齐,所以取其起始地址的[30:22]表示虚拟屏幕的地址。“视口”在这个4MB的空间内“滑动”,所以“视口”的起始地址就取[21:1]就可以了,它们之间的配合是一种偏移量的配合。但是由于内存中的数据是一行行的存放,所以需要使用偏移量来描述“窗口”每一行之间的偏移量。
二、硬件
TFT屏型号:东华3.5英寸LCD
cpu:S3C2440
SDRAM:K4S561632 x 2 (32M) x 2
电路图:
![]()
开发板与LCD屏接线图 LCD屏引脚与S3C2440接线表
其中:如何设置LCD输出视频?
1、设置GPG4口为LCD_PWREN
2、设置允许LCD_PWREN输出信号,通过LCDCON5寄存器中PWREN置1
3、设置视频输出和逻辑允许,通过LCDCON1寄存器中ENVID置1
4、设置控制信号的匹配极性(LCDCON5寄存器中INVVLNE 、INNNFAME、INVVD、INVVDEN 、INVPWER)
三、软件
3.1初始化
步骤
- GPIO设置初始化
- 显示模式初始化
- 帧缓冲区设置初始化
- 其他
//以下TFT参数:由自己根据东华3.5寸TFT(WXCAT35.PDF)中时序图和参数表
//经过验证TFT使用以下参数能正常工作
#define VBPD (15) //垂直同步信号的后肩
#define VFPD (12) //垂直同步信号的前肩
#define VSPW (3) //垂直同步信号的脉宽
#define HBPD (38) //水平同步信号的后肩
#define HFPD (20) //水平同步信号的前肩
#define HSPW (30) //水平同步信号的脉宽
#define CLKVAL_TFT (6)
#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 PNRMODE (3) // 设置为TFT屏
#define BPPMODE (12) // 设置为16bpp模式
//TFT_SIZE
#define LCD_XSIZE_TFT (320)
#define LCD_YSIZE_TFT (240)
#define SCR_XSIZE_TFT (320)
#define SCR_YSIZE_TFT (240)
#define M5D(n) ((n) & 0x1fffff)//只取21位数据
volatile unsigned short LCD_BUFFER[SCR_YSIZE_TFT][SCR_XSIZE_TFT];//定义帧缓冲,占用320*240*2字节
void TFT_InitHardware(void)
{
/*GPIO初始化--定义V[0]--V[23],和VM VFRAME VLINE VCLK控制信号*/
rGPCUP = 0x00000000;
rGPCCON = 0xaaaa02a9; //GPC口定义成:1、像素数据输出端口V[0]--V[7]
//2、VM VFRAME VLINE VCLK信号有效,
//3、而LCDVF2 LCDVF1 LCDVF0 LEND信号无效
rGPDUP = 0x00000000;
rGPDCON=0xaaaaaaaa; //GPD口定义成:1、像素数据输出端口V[8]--V[23]
/*显示初始化*/
rLCDCON1=(CLKVAL_TFT<<8)|(MVAL_USED<<7)|(PNRMODE<<5)|(BPPMODE<<1)|0;
//设置VCLK的分频比为6,VM信号的触发模式=each frame,
//显示模式为 TFT LCD panel,彩色模式为16bpp TFT,ENVID=0(禁止LCD信号输出)
//像素时钟:VCLK=HCLK/[(CLKVAL+1)*2]=100M/(7*2)=7.14M(3.5寸TFT的VCLK=6.4M,大于该值即可)
rLCDCON2=(VBPD<<24)|(LINEVAL_TFT<<14)|(VFPD<<6)|(VSPW);
//rLCDCON2--设置垂直方向各信号时间参数(即列控制寄存器)
//设置VBPD=15,VFPD=12,VSPW=5和LCD panel的垂直有效宽度=239
//LINEVAL_TFT--LCD最大显示行数, LINEVAL_TFT=LCD_YSIZE_TFT-1=240-1=239
rLCDCON3=(HBPD<<19)|(HOZVAL_TFT<<8)|(HFPD);
//rLCDCON3--设置水平方向各信号时间参数(即行控制寄存器)
//设置HBPD=238,LCD panel的水平有效宽度=319,HFPD=20
//HOZVAL_TFT--LCD最大显示列数 HOZVAL_TFT=LCD_XSIZE_TFT-1=320-1=319
rLCDCON4=(MVAL<<8)|(HSPW);
//设置MVAL=13,HSPW=30
rLCDCON5 = (1<<11) | (0<<10) | (1<<9) | (1<<8) | (0<<7) | (0<<6) | (1<<3) |(BSWP<<1) | (HWSWP);
//1、TFT显示模式16BPP时,使用数据格式5:6:5 2、在VCLK下降沿读取数据
//3、HSYNC脉冲的极性:反转,VSYNC脉冲的极性:反转 4、VD数据线表示数据极性:正常
//5、VDEN信号极性:正常 6、LCD_PWREN信号输出使能 7、禁止字节交换,允许半字节交换
/*帧缓冲区初始化*/
/*
LCDBANK:视屏缓冲区内存地址:30-22位
LCDBASEU:视屏缓冲区的开始地址21-1位
LCDBASEL:视屏缓冲区的结束地址21-1位
*/
/*rLCDSADDR1[29:21]表示LCDBANK,rLCDSADDR1[20:0]表示LCDBASEU*/
rLCDSADDR1=(((U32)LCD_BUFFER>>22)<<21)|M5D((U32)LCD_BUFFER>>1);
//在内存中设置显存(帧缓冲区)起始地址,其中LCD_BUFFER是定义存放图像的数组,
//以该数组的地址作为显存的起始地址。其中LCD_BUFFER[21:0]表示4Mbyte空间。
/*rLCDSADDR2[20:0]表示LCDBASEL*/
rLCDSADDR2=M5D( ((U32)LCD_BUFFER+(SCR_XSIZE_TFT*LCD_YSIZE_TFT*2))>>1 );//设置帧缓冲区结束地址
//LCDBASEL=(帧缓冲区结束地址)>>1+1
//等同 =LCDBASEU+(PAGEWITH+OFFSIZE)*(LINEVAL+1)
// =M5D((U32)LCD_BUFFER>>1+((320*240)*2)>>1)
// =M5D( ((U32)LCD_BUFFER+(SCR_XSIZE_TFT*LCD_YSIZE_TFT*2))>>1 )
//1、为什么乘以2?因为每个像素点由2个字节即16bit组成(因为LCD设置16bpp)。如果设置为24bpp,则乘以4。
//2、为什么M5D?因为计算缓冲区起始和结束地址时只需要A[20:0]
/* LCDSADDR3用于设置虚拟屏幕
OFFSIZE:虚拟屏幕左侧偏移的半字数(半字=16bit),如果不使用虚拟屏幕,设置为0
PAGEWITH:虚拟屏幕一行的半字数,如果不使用虚拟屏幕,设置为实际屏幕行的半字数。
其中半字由16位表示,等同一个16bpp像素点
*/
rLCDSADDR3=(((SCR_XSIZE_TFT-LCD_XSIZE_TFT)/1)<<11)|(LCD_XSIZE_TFT/1);
//设置虚拟屏的offset size和page width
//offset size=(SCR_XSIZE_TFT-LCD_XSIZE_TFT)/1=0
//page width=(LCD_XSIZE_TFT/1)=320
/*其他项初始化*/
rLCDINTMSK|=(3); // MASK LCD Sub Interrupt
rTCONSEL &= (~7) ; // Disable LPC3480
rTPAL=0; // Disable Temp Palette
}
3.2显示程序
3.2.1图片显示
//=============================================================
//语法格式: void TFT_Pitcure(int x0,int y0,int h,int l,unsigned char bmp[])
//实现功能: 在屏幕上指定坐标画一个指定大小的图片
//参数:
// x0 - 图片左上角x坐标
// y0 - 图片左上角y坐标
// h - 图片的高
// l - 图片的长
// bmp[] - 图片的模
//返回值: 无
//注:用Image2LCD取模 水平扫描 16位真色彩 高位在前
//=============================================================
void TFT_Pitcure(int x0,int y0,int height,int width,unsigned char bmp[])
{
int x,y;
U32 c;
int p = 0;
for( y = y0 ; y < width ; y++ )
{
for( x = x0 ; x < height ; x++ )
{
c = bmp[p+1] | (bmp[p]<<8) ;
if ( ( (x0+x) <SCR_XSIZE_TFT) && ( (y0+y) < SCR_YSIZE_TFT) )
LCD_BUFFER[y0+y][x0+x] = c ;
p = p + 2 ;//LCD_BUFFER数组的数据类型:unsigned short为2个字节
}
}
}
//=============================================================
//语法格式: void TFT_Pitcure(int x0,int y0,int h,int l,unsigned char bmp[])
//实现功能: 在屏幕上指定坐标画一个指定大小的图片
//参数:
// x0 - 图片左上角x坐标
// y0 - 图片左上角y坐标
// h - 图片的高
// l - 图片的长
// bmp[] - 图片的模
//返回值: 无
//注:用Image2LCD取模 水平扫描 16位真色彩 高位在前
//=============================================================
void TFT_Pitcure(int x0,int y0,int height,int width,unsigned char bmp[])
{
int x,y;
U32 c;
int p = 0;
for( y = y0 ; y < width ; y++ )
{
for( x = x0 ; x < height ; x++ )
{
c = bmp[p+1] | (bmp[p]<<8) ;
if ( ( (x0+x) <SCR_XSIZE_TFT) && ( (y0+y) < SCR_YSIZE_TFT) )
LCD_BUFFER[y0+y][x0+x] = c ;
p = p + 2 ;//LCD_BUFFER数组的数据类型:unsigned short为2个字节
}
}
}
3.3时序图
LCD控制器时序图
寄存器参数:
VSPW:垂直同步信号的脉宽,单位为1行(Line)的时间。
VFPD: 垂直同步信号的前肩,单位为1行(Line)的时间。
VBPD: 垂直同步信号的后肩,单位为1行(Line)的时间。
LINEVAL :垂直显示尺寸-1,即屏行宽-1。HBPD:水平同步信号的后肩,单位为1VCLK的时间。
HFPD:水平同步信号的前肩,单位为1VCLK的时间。
HSPW:水平同步信号的脉宽,单位为1VCLK的时间。
HOZVAL:水平显示尺寸-1,即屏列宽-1。由上图可知:扫描一帧所需的时间:=((VSPW+1)+(VBPD+1)+( LINEVAL+1)+(VFPD+1))个行时间。
扫描一行所所需的时间:= ((HSPW+1)+(HSPD+1)+(HFPD+1)+ (HOZVAL+1))个VCLK时间。而一个VCLK时间由LCD寄存器LCDCON1内的CLKVAL决定:=HCLK/[2*(CLKVAL+1)]因此扫描一帧所需的时间:T=[(VSPW+1)+(VBPD+1)+( LINEVAL+1)+(VFPD+1)]* [(HSPW+1)+(HSPD+1)+(HFPD+1)+ (HOZVAL+1)]* HCLK/[2*(CLKVAL+1)]即帧频率为:1/T
东华TFT型LCD(WXCAT35)时序图
参数表
WXCAT35时序表
由以上参数表可知:
1、 TFT的VCLK典型值=6.4M,所以外部提供给TFT的VCLK最好大于6.4M,这样能保证TFT正常显示。(以前提供VCLK=3.7M,导致FTF显示画面抖动)。实验板的HCLK=100M,CLKVAL=6,则 VCLK = HCLK/[(CLKVAL+1)x2]= 100/2*(6+1)= 7.14MHz,即满足要求。
2、 参数设置:(由上面东华TFT型LCD(WXCAT35)时序图和表1的参数表可知)
1 、VBPD:确定帧同步信号和帧数据传输前的一段延迟时间,是帧数据传输前延迟时间和行同步时钟间隔宽度的比值。
VBPD=帧数据传输前延迟时间/行同步时钟间隔宽度=VSYNC_Back_porch/HSYNC_Period (垂直同步信号的后肩)
=tvb/th=15
2、VFPD:确定帧数据传输完成后到下一帧同步信号到来的一段延迟时间,是帧数据传输后延迟时间和行同步时钟间隔宽度的比值
VFPD=帧数据传输后延迟时间/行同步时钟间隔宽度= VSYNC_front_porch/HSYNC_Period (垂直同步信号的前肩)
=tvf/th=12
3、VSPW:确定帧同步时钟脉冲宽度,是帧同步信号时钟宽度和行同步时钟间隔宽度的比值
VSPW =帧数据传输后延迟时间/行同步时钟间隔宽度= VSYNC_Pulsewidth/HSYNC_Period (垂直同步信号的脉宽)
=tvp/th=3
4、HBPD:确定行同步信号和行数据传输前的一段延迟时间,描述行数据传输前延迟时间内VCLK脉冲个数
HBPD=HSYNC_Back_porch (水平同步信号的后肩)=thb=38
5、HFPD:确定行数据传输完成后到下一行同步信号到来的一段延迟时间,描述行数据传输后延迟时间内VCLK脉冲个数
HFPD= HSYNC_Front_porch (水平同步信号的前肩)=thf=20
6、HSPW:确定行同步时钟脉冲宽度。描述行同步脉冲宽度时间内VCLK脉冲个数
HSPW= HSYNC_pusewidth (水平同步信号的脉宽)=thp=30
总结:编写LCD程序时时序参数由选用的TFT屏时序参数决定。
四、实测(待完善)
4.1显示图片
4.2显示图片做偏移(未实现)
4.3滚屏(为实现)