1、University of Shanghai for Science and Technology第七章 LCD液晶显示器 7.1 LCD显示器概述 LCD它是一种数字显示技术,可以通过液晶和彩色过滤器过滤光源,并在平面面板上产生图像。与传统的阴极射线管(CRT)相比,LCD占用空间小、低功耗、低辐射、无闪烁、降低视觉疲劳,具有很大的发展潜力。University of Shanghai for Science and Technology1.LCD显示器的分类n扭曲向列型(TN-Twisted Nematic);n超扭曲向列型(STN-Super TN);n双层超扭曲向列型(DSTN-Dou
2、ble-layer Super-Twisted Nematic);n薄膜晶体管型(TFT-Thin Film Transistor)。University of Shanghai for Science and Technology 2.LCD的常用指标 nPPI与分辨率 PPI是指每平方英寸所拥有的像素(Pixel)数目。可见,PPI数值越高就意味着显示屏能够以更高的密度显示图像。显示的密度越高,拟真度也就越高。目前通用的TFT液晶显示屏大部分只有100PPI,如果拥有高一倍的显示画质(200PPI),显示效果会更好。University of Shanghai for Science an
3、d Technologyn分辨率标准分辨率标准 目前市面上的分辨率标准多种多样,主要有VGA、SVGA、UXGA和SXGA+。其中SXGA+所代表的显示分辨率为1400 x1050。Quad-VGA是三菱公司的一种新分辨率标准,它所代表的分辨率1280 x960,与一般标准XGA的1280 x1024显示分辨率比较,Quad-VGA会较为扁平一点。University of Shanghai for Science and Technologyn尺寸标示尺寸标示 LCD显示器跟CRT显示器除显示方式不同以外,最大的区别就是尺寸的标示方法不一样。例如,CRT显示器在规格中标为17英寸,但实际可视
4、尺寸达不到17英寸,只有15英寸多些;而对于LCD显示器,如果标示为15.1英寸,那么可视尺寸就是15.1英寸。University of Shanghai for Science and Technologyn解析度解析度 LCD液晶显示器不像CRT显示器,它只支持“真实解析度”,通常等价于一般CRT显示器的最高解析度。其主要差别在于,LCD液晶显示器只有在“真实解析度”下才能表现最佳影像效果。解析度低于真实解析度时,影像可以被呈现,但影像无法如真实解析度般得到优化。University of Shanghai for Science and Technology7.2 嵌入式处理器的LCD
5、控制器7.2.1 LCD 控制器的接口 因为工作原理不同,液晶的显示接口时序可以分为STN和TFT两种。目前,一些嵌入式处理器可以同时支持STN和TFT的LCD显示器。以STN显示为例,从图7.1可以看出片内集成的LCD控制器可以产生必要的控制信号,如VFRAME、VLINE、VCLK和VM等。传输显示数据。LCD控制器的接口定义如表7-1示。University of Shanghai for Science and Technology图7.1LCD控制器的结构图University of Shanghai for Science and Technology信号描述功能VFRAME LC
6、D控制器和LCD驱动器的帧同步信号控制LCD的帧显示,LCD控制器在一个完整的帧被显示后发送此信号VLINELCD控制器和LCD驱动器的行同步信号LCD控制器通过它将水平移位寄存器中的内容显示到LCD上,LCD控制器一整行数据被传输到LCD驱动器后发送VLINEVCLK刷新时钟它是LCD控制器与LCD驱动器之间的像素时钟信号,LCD控制器在此信号上升沿发送数据,LCD驱动器则在下降沿采样数据VMLCD驱动器的交流信号LCD驱动器用此信号来改变行和列的电压极性以控制像素的显示与否VD7:0数据线LCD像素输出端口表表7-1 LCD7-1 LCD控制器的接口控制器的接口University of
7、Shanghai for Science and Technology7.2.2LCD控制器的设置 LCD驱动编写的主要工作就是正确设置对应于所用LCD屏的CPU寄存器。表7-2所示为嵌入式处理器S3C2410中与LCD相对应的寄存器,表中给出了各个寄存器的简单描述,如果想了解它们的详细设置,请参考S3C2410的用户手册。University of Shanghai for Science and Technology寄存器宏定义地址读/写描述复位LCD控制寄存器1LCDCON10 x4d000000读/写工作信号控制寄存器0 x0LCD控制寄存器2LCDCON20 x4d000004读/写
8、LCD水平/垂直尺寸定义0 x0LCD控制寄存器3LCDCON30 x4d000008读/写LCD控制寄存器30 x0LCD控制寄存器4LCDCON40 x4d00000c读/写LCD控制寄存器40 x0LCD控制寄存器5LCDCON50 x4d000010读/写LCD控制寄存器50 x0帧缓冲地址寄存器1LCDSADDR10 x4d000014读/写液晶类型和扫描模式定义0 x0帧缓冲地址寄存器2LCDSADDR20 x4d000018读/写设定显示缓冲区信息0 x0帧缓冲地址寄存器3LCDSADDR30 x4d00001c读/写设定虚拟屏偏移和页面宽度0 x0红色设置寄存器REDLUT0
9、x4d000020读/写定义8组红色数据查找表0 x0绿色设置寄存器GREENLUT0 x4d000024读/写定义8组绿色数据查找表0 x0蓝色设置寄存器BLUELUT0 x4d000028读/写定义8组蓝色数据查找表0 x0抖动模式寄存器DITHMODE0 x4d00004c读/写STN抖动模式寄存器0 x0临时调色板寄存器TPAL0 x4d000050读/写TFT临时调色寄存器,其值在下一帧时将变成视频数据0 x0LCD中断挂起寄存器LCDINTPND0 x4d000054读/写挂起LCD中断0 x0LCD中断源挂起寄存器LCDSRCPND0 x4d000058读/写挂起LCD中断源0
10、x0LCD中断屏蔽寄存器LCDINTMSK0 x4d00005c读/写屏蔽LCD中断源0 x3表表7-27-2LCDLCD控制器相关的设置控制器相关的设置University of Shanghai for Science and Technology1 设置VM、VFRAME、VLINE VM信号通过改变液晶的行列电压的极性来控制像素的显示,VM速率可以配置LCDCON1寄存器的MMODE位及LCDCON2寄存器的MVAL7:0。VM速率=VLINE速率/(2MVAL)University of Shanghai for Science and Technology VFRAME和VLINE
11、信号可以根据液晶屏的尺寸及显示模式,配置LCDCON2寄存器的HOZVAL和LINEVAL值,即:HOZVAL=(水平尺寸/VD数据位)-1 彩色液晶屏时:水平尺寸3水平像素点数 VD数据位:VD=4(4位单/双扫描模式)VD=8(8位单扫描模式)LINEVAL=垂直尺寸一1(单扫描模式)LINEVAL=(垂直尺寸2)-1 (双扫描模式)University of Shanghai for Science and Technology2设定VCLK VCLK是LCD控制器的时钟信号,它的计算需要先计算数据传送速率,由此设定的一个大于数据传送速率的值为VCLKVAL(LCDCONl 21:12)
12、。数据传送速率=水平只寸垂直尺寸帧速率模式值(MV)University of Shanghai for Science and Technology3帧速率帧速率可由以下公式得到:VCLK(Hz)=MCLK/(CLKVAL2),其中LKVAL大于数据传送速率且不小于2 帧速率(Hz)=(1/VCLK)*(HOZVAL+1)+(1/MCLK)*(WLH+WDLY+LINEBLANK)*(LINEVAL+1)-1 LINEBANK:水平扫描信号LINE持续时间设置(MCLK个数)。LINEVAL:显示屏的垂直尺寸。VCLK的计算还可以使用以下公式:VCLK(Hz)=(HOZVAL+1)/(1/(
13、帧速率(LINEVAL+1)-(WLH+WDLY+LINEBLANK)/MCLK)University of Shanghai for Science and Technology4.设定数据帧显示控制(LCDBASEU、LCDBASEL、PAGEWIDTH、OFFSIZE、LCDBANK)LCDBASEU设置显示扫描方式中的开始地址(单扫描方式)或高位缓存地址(双扫描方式)。LCDBASEL是设置双扫描方式的低位缓存开始地址。可用以下计算公式:LCDBASEL=LCDBASEU+(PAGEWIDTH+OFFSIZE)*(LINEVAL+1)PAGEWDTH是显示存储区的可见帧宽度(半字数)。
14、OFFSIZE是显示存储区的前行最后半字和后行第一个半字之间的半字数。LCDBANK是访问显示存储区的地址A27:22值,ENVID=1时该值不能改变。University of Shanghai for Science and Technology7.3基于Framebuffer 的LCD驱动程序 实际上,Linux为显示设备专门提供了一类驱动程序,叫做帧缓冲(Framebuffer)设备驱动程序。University of Shanghai for Science and Technology7.3.1 Framebuffer驱动结构 FrameBuffer的核心是一块供显示使用的内存。由
15、系统中显示机构将显示内存中的内容显示到显示设备上。帧缓冲驱动本质上是一个字符设备的驱动,但是具有自己的框架。Linux下FrameBuffer驱动的结构和逻辑都不复杂,主要需要构建驱动程序帧缓冲操作的数据结构struct fb_ops,在其中包含注册显示缓冲实现函数的指计。University of Shanghai for Science and Technology1.FrameBuffer驱动的作用 在程序设计中、对显示的操作即是对显示内存的操作。在简单的操作系统中,可以直接利用写显示内存的方法,获得显示的效果。在Linux操作系统中,提供了一种普遍的显示接口:FraraeBuffer驱
16、动。使用FrameBuffer驱动可以更方便地完成应用程序的开发和系统的移植。University of Shanghai for Science and Technology 如果仅仅是需要让系统显示出内容只需要向显示内存中写入数据,对于Linux,只需要切入到内核态,对显示内存进行操作即可。从这个角度来讲,用户不需要FrameBuffer时驱动也可以操作显示。FrameBuffer驱动的优点在于,它为显示程序的开发提供了一个框架。一方面,它封装了一部分对显示内存的操作,另一方面,它又对上层提供了统一的接口。开发者只需要实观FrameBuffer驱动对硬件的移植,就可以在上层使用FrameB
17、uffer驱动方便的接口。Linux中帧缓冲驱动主要涉及的文件是include/linux目录中的fb.h。University of Shanghai for Science and Technology 对于FrameBuffer驱动,不仅为用户自己的程序调用,还可以被Linux内核和各种GUI系统调用。由于Linux内核集成了很多对FrameBuffer驱动的操作,很多GUI系统的显示部分也是基于FrameBuffer驱动。Linux下的FrameBuffer驱动结构如图7-2所示。University of Shanghai for Science and Technology用户程序
18、用户程序GUIGUI系统系统LinuxLinux内核内核Frame Buffer Frame Buffer 驱动驱动硬件硬件 (LCD(LCD 控制器控制器 )移植层移植层统一调用接口统一调用接口图图7-2 Linux7-2 Linux下的下的FrameBufferFrameBuffer驱动结构驱动结构University of Shanghai for Science and Technology2FrameBuffer驱动结构 Linux的FrmneBuffer驱动从本质上,还是一种字符设备驱动程序,但是它不直接使用字符设备驱动程序的框架(file_operations),而是有自己的另外
19、一套框架。fb_info是一个描述FrameBuffer属性的数据结构,以linux2.6内核为例,其定义如下:University of Shanghai for Science and Technologystruct fb_info int node;int flags;struct fb_var_screeninfo var;/*显示屏变量*/struct fb_fix_screeninfo fix:/*显示屏固定量*/struct fb_monspecs monspecs;/*当前监视器规格*/struct work_struct queue;/*帧缓冲事件队列*/struct fb
20、_pixmap pixmap;/*图像硬件映射*/struct fb_pixmap sprite;/*硬件光标映射*/struct fb_cmap cmap;/*当前cmap*/struct list_head modelist;/*模式列表*/struct fb_ops *flops;struct device *device;University of Shanghai for Science and Technology#ifdef CONFIG_FB_TILEBLITTING struet fb_tile_ops*tileops;/*帧缓冲tile操作*/#endifchar_ iom
21、em*screen_base;/*虚拟地址*/unsigned long screen_size;/*IO重映射VRAM或者0*/void *pseudo_palene;/*为16位颜色的调色板*/#define FBINFO_STATE_RUNNING 0#define FBINFO_STATE_SUSPENDED 1 u32 state;/*硬件状态,例如:挂起*/void*fbcon_par:/*fbcon使用的私有区域*/*以下为硬件相关的*/void *par;;University of Shanghai for Science and Technology 在这个数据结构中最主要
22、的成员为数据结构struct fb_var_screeninfo,它描述了屏幕的状态,例如可见显示分辨率(visible resolution)、虚拟显示分辨率(virtual fesolution),虚拟显示偏移、像索深度等参数。其定义如下所示:University of Shanghai for Science and Technologystruct fb_vat_screeninfo _u32 xres;/*可见分辨率*/_u32 yres;_u32 xres_virtual;/*虚拟分辨率*/_u32 yres_virtual;_u32 xoffset;/*虚拟到可见的偏移量*/_u
23、32 yoffset;_u32 bits_per_pixel;_u32 grayscale;/*如果不为0灰度级代替彩色*/struct fb_bitfied red;/*如果为真色彩代表帧缓冲的位域*/University of Shanghai for Science and Technology _u32 grayscale;/*如果不为0灰度级代替彩色*/struct fb_bitfied red;/*如果为真色彩代表帧缓冲的位域*/struct fb_bitfied green;/*否则只有长度有意义*/struct fb_bitfied blue;struct fb_bitfied
24、 transp;/*透明度*/_u32 nonstd;/*!=0非标准像素格式*/_u32 activate;_u32 height;/*画面内存映射的高*/_u32 width;/*画面内存映射的宽*/_u32 accel_flags;/*(废弃)*/_u32 pixclock;/*每秒的像素时钟 */University of Shanghai for Science and Technology_u32 left_margin;/*画面事件同步的值*/_u32 right_margin;_u32 upper_margin;一u32 lower_margin;_u32 hsync_len;
25、/*水平同步的长度*/_u32 vsync_len;/*垂直同步的长度*/_u32 sync;_u32 vmode;_u32 rotate:/*顺时针转动角度*/_u32 reserved5;/*为兼容保留*/;University of Shanghai for Science and Technology 在struct fb_var_screeninfo中,支持虚拟显示屏,其概念为,显示内存比实际可见区域要大。可见区域实际上是显示内存中的一个部分,它是实际在LCD上显示的区域。在显示内存中,涉及的显示属性包括虚拟显存宽度、虚拟显存高度、定义偏移量x,偏移量y,可见区域宽度、可见区域高度。
26、虚拟显示屏的概念如图116所示。University of Shanghai for Science and Technology虚拟显存虚拟显存X X虚虚拟拟显显存存Y Y可见区域可见区域X X可可见见区区域域Y Y偏移量偏移量X X偏移量偏移量Y Y图116 虚拟显示屏的概念University of Shanghai for Science and Technology注意:struct fb_var_screeninfo定义了一个功能较为全面的显示信息,在一般的LCD控制器中,不是每种功能都具有,或者即使LCD控制器有这种功能,但是不实现也可以完成基本的操作。fb_info的成员str
27、uct fb_fix_screeninfo定义了显示输出设备的各种属性,包括显示缓冲的起始地址、显示缓冲长度、显示缓冲类型等。这参数在设置完成后,一般都是只读的。University of Shanghai for Science and Technologystruct fb_fix_screeninfo char id16;/*辨识字符串,例如:“TT Builtin”*/unsigned long smem_start;/*帧缓冲起始地址*/*物理地址*/_u32 smem_len;/*帧缓冲内存的长度*/_u32 type;_u32 type_aux;/*隔行扫描位平面的插入值*/_u
28、32 visual;_u16 xpanstep;_u16 ypanstep;_u16 ywrapstep;_u32 line_length;/*每行字节数*/unsigned long mmio_start;/*内存映射I/0起始地址(物理地址)*/_u32 mmio_len;/*内存映射I/O的长度*/_u32 accel;/*表示驱动的细节*/_u16 reserved3;/*为兼容保留*/;University of Shanghai for Science and Technology struct fb_ops是fb_info另外一个重要的成员它定义了各种对显示缓冲的操作,这个数据结
29、构由一系列的函数指针组成。struet fb_ops /*open/release and usage marking*/struct module*owner;int(*fb_open)(struct fb_info*info,int user);int(*fb_release)(struct fb_info*info,int user);ssize_t(*fb_read)(struct file*file,char_use*bur,size_t count,loff_t*ppos);University of Shanghai for Science and Technology ssiz
30、e_t(*fb_write)(struct file*file,const char user*bur,size_t count,loff_t*ppos);int(*fb_check_var)(struct fb_var _screeninfo*varstruct fb_info*info);int(*fb_set_par)(struct fb_info*info);int(*fb_setcolreg)(unsigned regno,unsigned red,unsigned green,unsigned blueunsigned transp,struct fb_info*info):int
31、(*fb_blank)(int blank,struct fb_info*info);int(*fb_pan_display)(struct fb_var_screeninfo*var,struct fb_info*info);void(*fb_fillrect)(struct fb_info*info,const struct fb_fillrect*rect);void(*fb_copyarea)(struct fb_info*info,const struct fb_copyarea*region);University of Shanghai for Science and Techn
32、ology void(*fb_imageblit)(struct fb_info*info,const struct fb_image*image);int(*fb_cursor)(struct fb_info*info,struct fb_cursor*cursor);void(*fb_rotate)(struct fb_info*info,int angle);int(*fb_sync)(struct fb_info*info);int(*fb_iocfl)(strect inode*inodestruct file*file,unsigned int cmd,unsigned long
33、arg,struct fb_info*info);int(*fb_compat ioctl)(struct file*f,unsigned cmd,unsigned long arg,struct fb_info*info int(*fb_mmap)(struct fb_info*info,struct file*file,struct vm_area_ struct*vma);University of Shanghai for Science and Technology 在struet fb_ops主要的成员包括缓冲的打开fb_open、缓冲的关闭fb_release、读fb_read、
34、写fb_write、控制fb_ioctl、内存映射fb_mmap,这些和一般字符设备驱动程序是对应的。其他操作还包括调整显示fb_pan_display、填允矩形fb_fillrect、区域复制fb_copyarea等。University of Shanghai for Science and Technology 在应用程序中,一种常用的方式是使用mmap操作映射FrameBuffer到内存。例如:#define Width 640#define HejgIlt 480 int fd;unsigned char*FrameBuffer;fd=open(“/dev/fb0”,O_RDWR);
35、FrameBuffer=mmap(NULL,Width*Height,-PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);/*显示区域操作*/*/close(fd);University of Shanghai for Science and Technology 以上程序是在应用程序中清空屏幕,首先将FrameBuffer作为文件打开,接下来,使用库函数mmap将FrameBuffer映射到内存,mmap在内部会调用驱动程序fb_ops。数据结构的成员fb_mmap完成内存映射。内存映射完成后,可以使用各种针对内存的操作控制显示缓冲区。显然,对显示区域的操作还需要知
36、道显示区域的像素格式(Pixel Format)。University of Shanghai for Science and Technology知识小结1.FrameBuffer驱动本质上是一个字符驱动程序。2.FrameBuffer驱动的核心数据结构是fb_info,它主要提供对显示内存映射的功能。University of Shanghai for Science and Technology7.3.2 虚拟显示缓冲驱动分析 在Linux内核中最为基本的FrameBuffer驱动是虚拟显示缓冲驱动(vfb),它并不针对具体的现实硬件,而是利用内存中开辟的虚拟显示内存模拟对显示的操作。因
37、此,实际上它并不可能完成显示的功能。vfb实际上可以作为一个显示驱动程序的模块,利用对它的更改,可以完成对显示硬件的移植。University of Shanghai for Science and Technology1虚拟帧缓冲的数据结构及初始化 在Linux中,“drivers/video目录的vfb.c文件是vfb驱动程序。其中定义vfb_driver为虚拟帧缓冲的驱动程序结构体,vfb_device是显示设备结构体。University of Shanghai for Science and Technologystatic struct device_driver vtb_driv
38、er=.name=“vfb”,.bus=&platform_bus_type,.probe=vfb_probe,.remove=vfb_remove,;slatic struct platform_device vfb_device=.name=“vfb”,.id=0,.dev=.release=vfb_platform_release,;University of Shanghai for Science and Technology int _init vfb_init(void)int rot=0;#ifndef MODULE char *option=NULL;if(fb_get_op
39、tions(“vfb”,&option)return-ENODEV;vfb_setup(option);#endif University of Shanghai for Science and Technologyif(!vfb_enable)return-ENXI0;ret=driver_register(&vfb_driver);if(!ret)ret=platform_device_register(&rfb_device);if(rot)driver_unregister(&vfb_driver);return ret;module init(vibinit);University
40、of Shanghai for Science and Technology 在虚拟显示缓冲中,vfb_init被注册为系统的初始化函数,完成系统的初始化工作。其中,vfb_driver是显示的驱动,vfb_device是显示的设备,driver_register()是linux2.6内核中对设备驱动自动注册的函数,它调用设备驱动数据结构(struct device_driver)中的probe成员完成对设备的注册。如果注册成功,则调用platform_device _register把平台设备注册到平台中。University of Shanghai for Science and Tech
41、nology!提示 在linux2.6中,设备驱动(对应结构struct device_driver)的注册调用函数driver_register(struct device_driver*),从其参数中得到probe和remove两个成员。这两个成员是两个函数指针,分别在设备驱动的探测和移除的时候使用然后调用platform_device_register(struct platform_device*)。University of Shanghai for Science and Technology 在VFB设备驱动中,驱动的检测成员在vfb_driver被定义为vfb _probe,因
42、此注册驱动的时候将调用该函数完成设备驱动的注册。在vfb_probe函数的操作中主要工作是完成了对该显示缓冲数据结构struct fb_info *info的初始化,并调用register_framebuffer(info)将其注册为显示缓冲区。University of Shanghai for Science and Technology 数据结构info是显示缓冲的基本结构,在该函数中完成了显示内存的开辟,显示内存地址的设置,并且通过info-fbops=&vfb_ops操作将各个操作函数的指针赋值给显示缓冲的数据结构。在vfb_ops中,包含了本驱动程序中的各个函数,由这些函数来控制对
43、虚拟显示缓冲的各种操作。University of Shanghai for Science and Technologystatic struct fb_ops vfb_ops=.fb_check_var =vfb_check_var,.fb_set_par=vfb_set_par,.fb_setcolreg=vfb_seteolreg,.fb_pan_display=vfb_pan_display,.fb_fillrect=cfb_fillrect,.fb_copyarea=cfb_copyarea,.fb_imageblit=cfb_imageblit,.fb_cursor=soft_c
44、ursor,.fb_mmap=vfb_mmap,;University of Shanghai for Science and Technology2虚拟帧缓冲的功能实现nvfb_check_var是一个变量检查的函数,它根据检查变量,调一些信息。nvfb_set_par()是虚拟帧缓冲设置参数的函数,由它计算根据帧缓冲虚拟的长宽计算出每一行的长度。nvfb_setcolreg()是设置一个颜色信息的函数,通过它可以把颜色信息设给硬件的寄存器。University of Shanghai for Science and Technologynvfb_pan_display()是利用虚拟缓冲去完
45、成显示区域调整的函数,在其中,并不需要完全重写显示区域,只需要将可以显示区域的地址赋值。n内存映射函数vfb_mmap,由于虚拟帧缓冲不需要内存映射功能,因此本函数直接返回错误代码。而在真实的驱动程序中,它是一个非常重要的函数,它的实现可以让调用者将帧缓冲驱动程序(视为文件)映射到内存,然后像操作普通内存一样操作显示缓冲区。University of Shanghai for Science and Technologyncfb_fillrect(填充矩形)、cfb_copyarea(赋值区域)和cfb_imageblit(绘制图像),它们都是驱动程序中公用的函数,将其指针赋值给相应的成员。University of Shanghai for Science and Technology