当前位置:文档之家› LCD驱动程序分析

LCD驱动程序分析

LCD驱动程序分析
LCD驱动程序分析

//****************************************************** *

//* 2007.6.18

//****************************************************** *

在/kernel/include/asm-arm/arch-s3c2410/bitfield.h 文件中:

#ifndef __ASSEMBLY__

#define UData(Data) ((unsigned long) (Data))

#else

#define UData(Data) (Data)

#endif

例:UData(5); = 5

/*

* MACRO: Fld

*

* Purpose

* The macro "Fld" encodes a bit field, given its size and its shift value

* with respect to bit 0.

*

* Note

* A more intuitive way to encode bit fields would have been to use their

* mask. However, extracting size and shift value information from a bit

* field''''s mask is cumbersome and might break the assembler (255-character

* line-size limit).

*

* Input

* Size Size of the bit field, in number of bits.

* Shft Shift value of the bit field with respect to bit 0.

*

* Output

* Fld Encoded bit field.

*/

#define Fld(Size, Shft) (((Size) << 16) + (Shft))

例:Fld(2,5); = 0x20005

/*

* MACROS: FSize, FShft, FMsk, FAlnMsk, F1stBit

*

* Purpose

* The macros "FSize", "FShft", "FMsk", "FAlnMsk", and "F1stBit" return

* the size, shift value, mask, aligned mask, and first bit of a

* bit field.

*

* Input

* Field Encoded bit field (using the macro "Fld").

*

* Output

* FSize Size of the bit field, in number of bits.

* FShft Shift value of the bit field with respect

to bit 0.

* FMsk Mask for the bit field.

* FAlnMsk Mask for the bit field, aligned on bit 0.

* F1stBit First bit of the bit field.

*/

#define FSize(Field) ((Field) >> 16)

例:FSize(0x20005); = 2

#define FShft(Field) ((Field) & 0x0000FFFF)

例:FShft(0x20005); = 5

/*

* MACRO: FInsrt

*

* Purpose

* The macro "FInsrt" inserts a value into a bit field by shifting the

* former appropriately.

*

* Input

* Value Bit-field value.

* Field Encoded bit field (using the macro "Fld").

*

* Output

* FInsrt Bit-field value positioned appropriately.

*/

#define FInsrt(Value, Field) \

(UData (Value) << FShft (Field))

例:FInsrt(0x3, 0x20005); = 0x3 << 0x0005 = 0x60

------------------------------------------------------------------------

在/kernel/include/asm-arm/arch-s3c2410/hardware.h 文件中:

/*

* S3C2410 internal I/O mappings

*

* We have the following mapping:

* phys virt

* 48000000 e8000000

*/

#define VIO_BASE 0xe8000000 /* virtual start of IO space */

#define PIO_START 0x48000000 /* physical start of IO space */

#define io_p2v(x) ((x) | 0xa0000000)

#define io_v2p(x) ((x) & ~0xa0000000)

# define __REG(x) io_p2v(x)

# define __PREG(x) io_v2p(x)

这里,在实际的寄存器操作中,都用__REG(x) 宏将物理地址转换为了虚拟地址,然后再对这些虚拟地址进行读写操作。

------------------------------------------------------------------------

当应用程序对设备文件进行ioctl操作时候会调用它们。对于fb_get_fix(),应用程序传入的是fb_fix_screeninfo结构,在函数中对其成员变量赋值,主要是smem_start(缓冲区起始地址)和smem_len(缓冲区长度),最终返回给应用程序。

在/kernel/drivers/video/s3c2410fb.c 文件中的

s3c2410fb_map_video_memory 函数中:

fbi->fb.fix.smem_len = fbi->max_xres * fbi->max_yres * fbi->max_bpp / 8;

fbi->map_size = PAGE_ALIGN(fbi->fb.fix.smem_len + PAGE_SIZE);

fbi->map_cpu = consistent_alloc(GFP_KERNEL,

fbi->map_size,

&fbi->map_dma);

if (fbi->map_cpu)

{

fbi->screen_cpu = fbi->map_cpu + PAGE_SIZE;

fbi->screen_dma = fbi->map_dma + PAGE_SIZE;

fbi->fb.fix.smem_start = fbi->screen_dma;

}

在/kernel/include/asm-arm/proc-armo/page.h 文件中:

/* PAGE_SHIFT determines the page size. This is configurable. */

#if defined(CONFIG_PAGESIZE_16)

#define PAGE_SHIFT 14 /* 16K */

#else /* default */

#define PAGE_SHIFT 15 /* 32K */

#endif

在/kernel/include/asm-arm/page.h 文件中:

#define PAGE_SIZE (1UL << PAGE_SHIFT)

#define PAGE_MASK (~(PAGE_SIZE-1))

/* to align the pointer to the (next) page boundary */

#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)在/kernel/arch/arm/mm/consistent.c 文件中:

/*

* This allocates one page of cache-coherent memory space and returns

* both the virtual and a "dma" address to that space. It is not clear

* whether this could be called from an interrupt context or not. For

* now, we expressly forbid it, especially as some of the stuff we do

* here is not interrupt context safe.

*

* Note that this does *not* zero the allocated area!

*/

void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)

这里首先计算出需要视频缓冲区的大小(LCD屏的宽度 * LCD 屏的高度 * 每像素的位数 / 每字节的位数)

fbi->fb.fix.smem_len = 240*320*16/8 = 0x25800 =150K(9.375个PAGE)

PAGE_SHIFT = 14

PAGE_SIZE = 1<<14 = 0x4000 = 16K (1个PAGE)

PAGE_MASK = 0xFFFFC000

fbi->map_size = PAGE_ALIGN(fbi->fb.fix.smem_len +

PAGE_SIZE) = PAGE_ALIGN(150K + 16K) = PAGE_ALIGN(166K) = (166K + 16K - 1) & 0xFFFFC000 = 0x2D7FF & 0xFFFFC000 = 0x2C000 =176K

consistent_alloc(GFP_KERNEL, 176K, &fbi->map_dma);

最后得到:

framebuffer(物理地址)

|---------------|

| ... |

-------|---------------| <-- fbi->map_dma

| 16K |

分配了 |---------------| <-- fbi->screen_dma =

fbi->fb.fix.smem_start

176K | |

共11个 | | 160K = 10个PAGE

PAGE | 160K | 可以容下所需的150K 视频缓冲区大小 (16K) | |

| |

-------|---------------|-------

| ... |

|---------------|

//****************************************************** *

//* 2007.6.19

//****************************************************** *

在/kernel/drivers/video/s3c2410fb.c 文件中的

s3c2410fb_activate_var 函数中:

unsigned long VideoPhysicalTemp = fbi->screen_dma;

这里已经得到了framebuffer 在内存中的起始地址为VideoPhysicalTemp,地址数据位为A[30:0]。

new_regs.lcdcon1 = fbi->reg.lcdcon1 & ~LCD1_ENVID;

new_regs.lcdcon2 = (fbi->reg.lcdcon2 & ~LCD2_LINEVAL_MSK) | LCD2_LINEVAL(var->yres - 1);

/* TFT LCD only ! */

new_regs.lcdcon3 = (fbi->reg.lcdcon3 & ~LCD3_HOZVAL_MSK) | LCD3_HOZVAL(var->xres - 1);

new_regs.lcdcon4 = fbi->reg.lcdcon4;

new_regs.lcdcon5 = fbi->reg.lcdcon5;

LCDCON1 首先需要禁止视频输出才能进行寄存器的设置,然后对LCDCON2,LCDCON3 进行设置,主要是增加LINEVAL 和HOZVAL 这两个显示尺寸的参数。LCDCON4,LCDCON5 按原来配置设置。

LCDBANK[29:21] 为系统内存中视频缓冲区在系统存储器内的段

地址的A[30:22]

LCDBASEU[20:0] 为LCD framebuffer 的起始地址的A[21:1] LCDBASEL[20:0] 为LCD framebuffer 的结束地址的A[21:1] OFFSIZE[21:11] 为某一行的第一个半字与前一行最后一个半字之间的距离(单位:半字数,即2个字节)

PAGEWIDTH[10:0] 为显示存储区的可见帧宽度(单位:半字数,即2个字节)

new_regs.lcdsaddr1 =

LCDADDR_BANK(((unsigned long)VideoPhysicalTemp >> 22)) | LCDADDR_BASEU(((unsigned long)VideoPhysicalTemp >> 1));

new_regs.lcdsaddr2 = LCDADDR_BASEL(

((unsigned long)VideoPhysicalTemp + (var->xres * 2 * (var>yres))) >> 1);

这里LCDADDR_BASEL 的计算方法为用framebuffer 在内存中的起始地址VideoPhysicalTemp,加上framebuffer 的大小(LCD 屏的宽度 * LCD屏的高度 * 每像素的位数 / 每字节的位数),得到framebuffer 在内存中的结束地址,然后右移1位。

new_regs.lcdsaddr3 = LCDADDR_OFFSET(0) |

(LCDADDR_PAGE(var->xres));

这里PAGEWIDTH 的计算方法为:LCD屏的宽度*每像素的位数/16位(半字)。

问题:以上这些操作是否已经对DMA 控制器进行了设置?

我认为这里将framebuffer 在内存中的起始地址为VideoPhysicalTemp 变换后载入LCDADDR1,LCDADDR2,LCDADDR3 中就已经完成了对LCDCDMA 控制器的源数据的基地址设置,当打开LCDCON1 |= LCD1_ENVID; 后就可以由LCDCDMA 控制器自动从framebuffer 中传数据到LCD 屏幕了。

------------------------------------------------------------------------

在/kernel/drivers/video/s3c2410fb.c 文件中的xxx_stn_info 结构体初始化中:

lcdcon5 : LCD5_FRM565 | LCD5_INVVLINE | LCD5_INVVFRAME | LCD5_HWSWP | LCD5_PWREN,

INVVCLK , INVLINE , INVFRAME , INVVD :通过前面的时序图,我们知道,CPU的LCD控制器输出的时序默认是正脉冲,而LCD需要VSYNC(VFRAME)、VLINE(HSYNC)均为负脉冲,因此 INVLINE 和 INVFRAME 必须设为“1 ”,即选择反相输出。 INVVDEN ,INVPWREN , INVLEND 的功能同前面的类似。

PWREN 为LCD电源使能控制。在CPU LCD控制器的输出信号中,有一个电源使能管脚LCD_PWREN,用来做为LCD屏电源的开关信号。

其中LCD5_HWSWP 一项,设置了LCD从内存中显示数据时,经过了半字交换。

16BPP Display

(BSWP = 0, HWSWP = 0)

D[31:16] D[15:0]

000H P1 P2

004H P3 P4

008H P5 P6

...

(BSWP = 0, HWSWP = 1)

D[31:16] D[15:0]

000H P2 P1

004H P4 P3

008H P6 P5

...

像素显示顺序如下:

P1 P2 P3 P4 P5 ...

例如:内存地址的数据为:0x11223344 (32位)

系统存储器采用Big-Endian(大端模式)存储格式,地址数据格式如下:

D[31:16] D[15:0]

00 01 02 03

00H 0x11 0x22 0x33 0x44

(0x1122) (0x3344)

04H ...

08H ...

则首先显示0x3344 的数据到第一个像素,然后再显示0x1122 到第二个像素。

系统存储器采用Little-Endian(小端模式)存储格式,地址数据格式如下:

D[31:16] D[15:0]

03 02 01 00

00H 0x11 0x22 0x33 0x44

(0x1122) (0x3344)

04H ...

08H ...

则首先显示0x3344 的数据到第一个像素,然后再显示0x1122 到第二个像素。

//****************************************************** *

//* 2007.6.20

//****************************************************** *

在/kernel/arch/arm/mm/consistent.c 文件中的

consistent_alloc 函数中:

void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)

{

...

virt = page_address(page);

*dma_handle = virt_to_bus(virt);

ret = __ioremap(virt_to_phys(virt), size, 0);

...

}

这里调用该函数来分配一段内存空间有两个返回值,一个返回值返回给了ret 指针,另一个返回值返回给了dma_handle 指针。virt_to_bus 和virt_to_phys 函数的调用可以参考下面的分析。经过分析这两个函数作用一样,都是将virt 这个虚拟地址转换为物理地址。所以返回给指针dma_handle 的是所分配内存的起始地址(物理地址)。__ioremap 函数的调用也可以参考下面的说明,该函数也返回所分配内存的起始地址(虚拟地址),不过是经过I/O 内存映射的,把物理地址转换为了虚拟地址。

这样一来就很清楚了,返回的framebuffer 的物理地址给了指针dma_handle,也就是fbi->map_dma,到fbi->screen_dma,再到fbi->fb.fix.smem_start,最后到了指针VideoPhysicalTemp,这样写入到LCDADDR1,LCDADDR2 寄存器中的framebuffer 的地址其实都是物理地址。

而返回的framebuffer 的虚拟地址给了指针ret,也就是

fbi->map_cpu,到fbi->screen_cpu,最后到了

display->screen_base(见/kernel/drivers/video/s3c2410fb.c 文件中的s3c2410fb_set_var 函数)。

--------------------------------------------------------

----------------

在/kernel/drivers/video/fbmem.c 文件中:

/**

* register_framebuffer - registers a frame buffer device * @fb_info: frame buffer info structure

*

* Registers a frame buffer device @fb_info.

*

* Returns negative errno on error, or zero for success.

*

*/

int

register_framebuffer(struct fb_info *fb_info)

/**

* unregister_framebuffer - releases a frame buffer device * @fb_info: frame buffer info structure

*

* Unregisters a frame buffer device @fb_info.

*

* Returns negative errno on error, or zero for success.

*

*/

int

unregister_framebuffer(struct fb_info *fb_info)

static int

fb_open(struct inode *inode, struct file *file)

static int

fb_release(struct inode *inode, struct file *file)

static ssize_t

fb_read(struct file *file, char *buf, size_t count, loff_t *ppos)

static ssize_t

fb_write(struct file *file, const char *buf, size_t count, loff_t *ppos)

static int

fb_ioctl(struct inode *inode, struct file *file, unsigned

int cmd,

unsigned long arg)

static int

fb_mmap(struct file *file, struct vm_area_struct * vma)在该文件中包含了所有驱动LCD 的函数。在fb_read 和

fb_write 这两个函数中,都对framebuffer 进行了操作。

fb_read 函数中:

char *base_addr;

base_addr = info->disp->screen_base;

count -= copy_to_user(buf, base_addr+p, count);

fb_write 函数中:

char *base_addr;

base_addr = info->disp->screen_base;

count -= copy_from_user(base_addr+p, buf, count);

所读写的framebuffer 的基地址就是disp->screen_base,也就是fbi->screen_cpu 所指的framebuffer 的虚拟地址。

从而得到:

framebuffer(虚拟地址)

LCD驱动分析_LCD控制器设置及代码详解

LCD驱动分析_LCD控制器设置及代码详解 1. LCD工作的硬件需求: 要使一块LCD正常的显示文字或图像,不仅需要LCD驱动器,而且还需要相应的LCD 控制器。在通常情况下,生产厂商把LCD驱动器会以COF/COG的形式与LCD玻璃基板制作在一起,而LCD控制器则是由外部的电路来实现,现在很多的MCU内部都集成了LCD控制器,如S3C2410/2440等。通过LCD控制器就可以产生LCD驱动器所需要的控制信号来控制STN/TFT屏了。 2. S3C2440内部LCD控制器结构图: 我们根据数据手册来描述一下这个集成在S3C2440内部的LCD控制器: a:LCD控制器由REGBANK、LCDCDMA、TIMEGEN、VIDPRCS寄存器组成; b:REGBANK由17个可编程的寄存器组和一块256*16的调色板内存组成,它们用来配置LCD控制器的; c:LCDCDMA是一个专用的DMA,它能自动地把在侦内存中的视频数据传送到LCD驱动器,通过使用这个DMA通道,视频数据在不需要CPU的干预的情况下显示在LCD屏上; d:VIDPRCS接收来自LCDCDMA的数据,将数据转换为合适的数据格式,比如说4/8位单扫,4位双扫显示模式,然后通过数据端口VD[23:0]传送视频数据到LCD驱动器;e:TIMEGEN由可编程的逻辑组成,他生成LCD驱动器需要的控制信号,比如VSYNC、HSYNC、VCLK和LEND等等,而这些控制信号又与REGBANK寄存器组中的LCDCON1/2/3/4/5的配置密切相关,通过不同的配置,TIMEGEN就能产生这些信号的不同形态,从而支持不同的LCD驱动器(即不同的STN/TFT屏)。 3. 常见TFT屏工作时序分析: LCD提供的外部接口信号:

LCD显示屏的器件选择和驱动电路设计

LCD显示屏的器件选择和驱动电路设计 如何实现LCD平板显示屏驱动电路的高性能设计是当前手持设备设计工程师面临的重要挑战。本文分析了LCD显示面板的分类和性能特点,介绍了LCD显示屏设计中关键器件L DO和白光LED的选择要点,以及电荷泵LED驱动电路的设计方法。 STN-LCD彩屏模块的内部结构如图1所示,它的上部是一块由偏光片、玻璃、液晶组成的LCD屏,其下面是白光LED和背光板,还包括LCD驱动IC和给LCD驱动IC提供一个稳定电源的低压差稳压器(LDO),二到八颗白光LED以及LED驱动的升压稳压IC。 STN-LCD彩屏模块的电路结构如图2所示,外来电源Vcc经LDO降压稳压后,向LCD驱动IC如S6B33BOA提供工作电压,驱动彩色STN-LCD的液晶显示图形和文字;外部电源Vcc经电荷泵升压稳压,向白光LED如NACW215/NSCW335提供恒压、恒流电源,LED的白光经背光板反射,使LCD液晶的65K色彩充分表现出来,LED的亮度直接影响LCD色彩的靓丽程度。

LCD属于平板显示器的一种,按驱动方式可分为静态驱动(Static)、单纯矩阵驱动(Simple Matrix)以及有源矩阵驱动(Active Matrix)三种。其中,单纯矩阵型又可分为扭转式向列型(Twisted Nematic,TN)、超扭转式向列型(Super Twisted Nematic,STN),以及其它无源矩阵驱动液晶显示器。有源矩阵型大致可区分为薄膜式晶体管型(ThinFilmTr ansistor,TFT)及二端子二极管型(Metal/Insulator/Metal,MIM)两种。TN、STN及TFT型液晶显示器因其利用液晶分子扭转原理的不同,在视角、彩色、对比度及动画显示品质上有优劣之分,使其在产品的应用范围分类亦有明显差异。以目前液晶显示技术所应用的范围以及层次而言,有源矩阵驱动技术是以薄膜式晶体管型为主流,多应用于笔记本电脑及动画、影像处理产品;单纯矩阵驱动技术目前则以扭转向列以及STN为主,STN液晶显示器经由彩色滤光片(colorfilter),可以分别显示红、绿、蓝三原色,再经由三原色比例的调和,可以显示出全彩模式的真彩色。目前彩色STN-LCD的应用多以手机、PDA、数码相机和视屏游戏机消费产品以及文字处理器为主。 器件选择 1.LDO选择。由于手机、PDA、数码相机和视屏游戏机消费产品都是以电池为电源,随着使用时间的增长,电源电压逐渐下降,LCD驱动IC需要一个稳定的工作电压,因此设计电路时通常由一个LDO提供一个稳定的 2.8V或 3.0V电压。LCM将安装在手机的上方,与手机的射频靠得很近,为了防止干扰,必须选用低噪音的LDO,如LP2985、AAT3215。 2.白光LED。按背光源的设计要求,需要前降电压(VF)和前降电流(IF)小、亮度高(500-1800mcd)的白光LED。以手机LCM为例,目前都使用3-4颗白光LED,随着LED 的亮度增加和手机厂商要求降低成本和功耗,预计到2004年中LCM都会选用2颗高亮度白光LED(1200-2000mcd),PDA和智能手机由于LCD屏较大会按需要使用4-8颗白光LED。NAC W215/NSCW335和EL99-21/215UCW/TR8是自带反射镜的白光LED,EL系列其亮度分为T、S、R三个等级,T为720-1000mcd,S为500-720mcd,都是在手机LCD背光适用之列。 LED驱动电路设计

LCD驱动程序分析

//****************************************************** * //* 2007.6.18 //****************************************************** * 在/kernel/include/asm-arm/arch-s3c2410/bitfield.h 文件中: #ifndef __ASSEMBLY__ #define UData(Data) ((unsigned long) (Data)) #else #define UData(Data) (Data) #endif 例:UData(5); = 5 /* * MACRO: Fld * * Purpose * The macro "Fld" encodes a bit field, given its size and its shift value

* with respect to bit 0. * * Note * A more intuitive way to encode bit fields would have been to use their * mask. However, extracting size and shift value information from a bit * field''''s mask is cumbersome and might break the assembler (255-character * line-size limit). * * Input * Size Size of the bit field, in number of bits. * Shft Shift value of the bit field with respect to bit 0. * * Output * Fld Encoded bit field. */

lcd16824驱动程序

#include #define fuc_PERIPH SYSCTL_PERIPH_GPIOE #define fuc_PORT GPIO_PORTE_BASE #define rs_PIN GPIO_PIN_0 #define rw_PIN GPIO_PIN_1 #define en_PIN GPIO_PIN_2 #define lcd_PERIPH SYSCTL_PERIPH_GPIOD #define lcd_PORT GPIO_PORTD_BASE #define lcd_PINS 0xff #define SysCtlPeriEnable SysCtlPeripheralEnable #define SysCtlPeriDisable SysCtlPeripheralDisable #define GPIOPinTypeIn GPIOPinTypeGPIOInput #define GPIOPinTypeOut GPIOPinTypeGPIOOutput #define GPIOPinTypeOD GPIOPinTypeGPIOOutputOD #define FIRST_ADDR 0 //定义字符/汉字显示起始位置 unsigned char CGRAM[]={ 0x08,0x20,0x1c,0x10,0x1c,0x1c,0xff,0x9e,0x7f,0x1e,0x1c,0x1f,0x3e,0x1f,0x3e, 0x1f, 0x77,0x1f,0x41,0x3f,0x00,0x7e,0x00,0xfe,0x83,0xfc,0x7f,0xf8,0x3f,0xf0,0x0f, 0xc0, }; unsigned char BMP1[]; unsigned char BMP2[]; unsigned char BMP3[]; unsigned char BMP4[]; unsigned char BMP5[]; unsigned char BMP6[]; unsigned char BMP7[]; unsigned char BMP8[]; unsigned char Num[]={'0','1','2','3','4','5','6','7','8','9','.'}; void delay (int m) { i nt n; f or(n=0;n<=m;n++); } void check(void) //判断是否忙碌 {

LCD数码管的驱动

LED数码管的驱动是比较简单也容易理解的,多位数码管一般是LED阵列的形式,每个数字使用一个公共端,不同数字的对应同笔段使用一个控制端;驱动采用分时扫描没个数字位,动态显示。但是LED比较费电,我想做一个用电池供电的钟,用发光管电池就撑不了多久了。于是我考虑用液晶。 在这边的电子市场我买到一个4位笔段式液晶屏,4个数字最中间有冒号,边上还有几个箭头符号,一共有15个引脚,正合适用A VR来驱动做一个钟。 笔段式LCD屏的结构与LED数码管很相似,但是由于是液晶,工作机理上不同,驱动方式也有很大差异: (1) LED有正负之分,液晶笔划没有。 (2) LED在直流电压下工作,液晶需要交流电压,防止电解效应。 (3) LED需要电流提供发光的能量,液晶笔划显示状态下电流非常微弱。 (4) LED对微小电流不反应,液晶则很敏感。 不难看出,用LED的驱动方式来对待LCD屏是行不通的。我在买回来测试这块屏之前没有意识到,于是走了不少的弯路。与LED驱动不同的是需要给每个笔划加上一个交流电压。一般用30-60Hz的方波就可以了,频率再低显示会有所波动,频率高了功耗也会增加,因为LCD对电路呈现容性。而且,正负电压都可以“点亮”液晶。 好在A VR的I/O口可以三态输出,也就是除了高/低电平,还可以呈现高阻抗,相当于断开连接。于是我想到了这样的办法:不需要显示的那一组笔划对应的公共端悬空(I/O口选择三态),那么就不会加上电压了。照这个思路,我的实验电路焊好,出来的显示却是一团糟:笔划都黑了看不清。我这才考虑到液晶本身的问题:阻抗高,而且有电容,是不可一边悬空的!这个道理也许跟CMOS输入端差不多。查找了一些关于液晶的资料,大致知道LCD屏不是那么简单的,驱动方式通常是1/N, 也就是电压不止高低两档。可是单片机I/O没有那么多输出状态可以选择。 1/2 Bias驱动 不显示的液晶笔划两端电压相等,显示的不等。这样一个要求在扫描方式 下不能满足,于是改为电压等级不同。1/2 Bias驱动就是这样的,如下: COM1 V+ ---- ---- 1/2 ---- ---- ---- ---- GND ---- ---- COM2 V+ ---- ---- 1/2 ---- ---- ---- ---- GND ---- ---- SEG1 V+ -------- -------- 1/2 GND -------- -------- SEG2 V+ ---- -------- ---- 1/2 GND -------- --------

关于TFT_LCD驱动IC市场分析报告

T F T-L C D驱动I C市场分析 前言 2000年,真是LCD驱动IC热热闹闹的一年。日韩大幅扩产LCD面板,台湾厂商面板产能逐渐开出,对驱动IC需求日益增加,99年底开始缺货的驱动IC更是雪上加霜。市场需求明显,使LCD驱动IC已逐渐成为受到业界嘱目的明星产业。 一、LCD驱动IC的关键技术问题 1、液晶显示器显像原理 2、驱动IC驱动方式 3、高频高压,模拟设计不易 TFT-LCD 要表现出彩色,是靠红绿蓝三个子像素浓度(色阶)的组合。浓度的控

制是由Source驱动IC输入电压信号决定。计算机图形的彩色浓度是指每个像素包含彩色信息的数据位数量,随着数据位的增加,彩色的数量也随之增加。为了在TFT-LCD 上表现CRT的效果,就必须有足够的灰度等级来获得1,600万多种彩色。目前是用8bit 储存色调控制,每个子像素有2的8次方等于256个色阶,三个子像素合成一个像素的颜色,256×256×256=1670万个颜色。所以Source驱动IC根据图形控制器送出的8位数据调整输出的电压,因此在设计上比较困难。数字IC只用于处理1和0,其中的晶体管只要能够区分开与关的状态,作为开关使用即可,不需做到太精确。但对于Source驱动IC来说,对电压和电流的控制就要精确的多,这关系着LCD的穿透率(即亮度),若不同的输出点,其电压差超过一定的规格则可看到显示画面不均匀的现象。而欲达此规格,不仅制造工艺上要有一定的稳定度,也需要相当的IC设计技术。如前所说,模拟的东西就是要靠经验。 Gate驱动IC的设计难度就不若Source,因为对于电压和电流要求不那幺严苛。但为求对比明显,Gate驱动IC输出的电压要够大才能使液晶分子扭转的够快,因此其所承受的电压高达40伏特。而在LCD显示面板尺寸持续增加,同时对于显示品质越来越重视的情况下,Gate驱动IC的设计与制造难度会增加。 4、产品品质为关键,单凭低价不易成 因此,关于LCD驱动IC,重要的不是能不能work,而是显示的品质如何。具有设计驱动IC能力并不难,但是要能通过客户的验证才是最关键的。很多IC放在密闭的机壳里,效能的差异并不是很明显,因此只要堪用,价格便宜还是有人买。但驱动IC 显现出来的效果好坏是很明显能够区分的,一台8、9百美元的LCD监视器如果因为这一颗4美元的驱动IC而不为市场所接受,是怎幺算都划不来的。所以新进业者在刚开始产品品质还不稳定时,想要利用低价抢进市场的方式是不太容易的。

LCD驱动注意事项

(1) 液晶显示模式 并行:MCU接口、RG战口、Vysnc接口 串行:SPI接口、MDDI接口 (2) 屏幕颜色实质上即为色阶的概念。色阶是表示手机液晶显示屏亮度强弱的指数标准,也就是通常所说的色彩指数。目前彩屏手机的色阶指数从低到高可分三个层次,最低单色,其次是256色、4096 色、65536 色;目前最高的为26 万色。256=2 的8 次方,即8 位彩色,依次律推,65536 色=2 的16 次方,即通常所说的16 位真彩色,26万=2的18次方,也就是18 位真彩。其实65536色已基本可满足我们肉眼的识别需求。 (3) 分辨率 LCD的分辨率与CRT显示器不同,一般不能任意调整,它是制造商所设置和规定的。分辨率是指屏幕上每行有多少像素点、每列有多少像素点。手机上LCD 的分辨率一般是176点X 220行的QCIF显示模式和240点X 320行的QVG;显示模式。 (4) 刷新率 LCD刷新频率是指显示帧频,亦即刷新一帧屏所需要的时间,与屏幕扫描速度及避免屏幕闪烁的能力相关。也就是说刷新频率过低,可能出现屏幕图像闪烁或抖动。 (5) 可视角度 指从不同的方向清晰地观察屏幕上所有内容的角度,这与LCD是DSTN还是TFT有很大关系。因为前者是靠屏幕两边的晶体管扫描屏幕发光,后者是靠自身每个像素后面的晶体管发光,其对比度和亮度的差别,决定了它们观察屏幕的视角有较大区别。DSTN- LCD一般只有60度,TFT- LCD则有160度。 (6) 响应时间响应时间愈小愈好,它反应了液晶显示器各象素点对输入信号反应的速度,即pixel 由暗转亮或由亮转暗的速度。响应时间越小则使用者在看运动画面时不会出现尾影拖拽的感觉。一般会将反应速率分为两个部份:Rising 和Falling ,而表示时以两者之和为准。 2. 接口形式: (1) 并行方式 a、MCU接口 目前主要有i80和m68两种类型。这种LCD模式须LCD有自己的GRAM b、RG肢口: 通过时钟同步来实现同步传输,此模式不需要LCD有GRAM来缓存数据。接口如下:

linux的lcd驱动详细讲解

嵌入式驱动程序Day12 Top 1. LCD驱动设计开发 1 LCD驱动设计开发 1.1问题 通过led驱动开发掌握linux内核framebuffer 驱动开发通用方法。 1.2方案 一、帧缓冲(Framebuffer )。 帧缓冲(Framebuffer )是Linux为显示设备提供的一个接口,Linux抽象出FrameBuffer这个设备来供用户态进程实现直接写屏。Framebuffer机制模仿显卡的功 能,将显卡硬件结构抽象掉,可以通过Framebuffer的读写直接对显存进行操作。用户 可以将Framebuffer看成是显示内存的一个映像,将其映射到进程地址空间之后,就可以直接进行读写操作,而写操作可以立即反应在屏幕上。这种操作是抽象的,统一的。用户不必关心物理显存的位置、换页机制等等具体细节。这些都是由Framebuffer 设备驱动 来完成的。 Framebuffer本身不具备任何运算数据的能力,就只好比是一个暂时存放水的水池。CPU将运算后的结果放到这个水池,水池再将结果流到显示器,中间不会对数据做处 理。应用程序也可以直接读写这个水池的内容。在应用程序中,一般通过将FrameBuffer 设备映射到进程地址空间的方式使用,比如下面的程序就打开/dev/fbO 设备,并通过mmap系统调用进行地址映射。 FrameBuffer设备还提供了若干ioctl 命令,通过这些命令,可以获得显示设备的 一些固定信息(比如显示内存大小)、与显示模式相关的可变信息(比如分辨率、象素结构、每扫描线的字节宽度),以及伪彩色模式下的调色板信息等等。 二、FrameBuffer 在Linux中的实现和机制。 Framebuffer对应的源文件在linux/drivers/video/ 目录下。总的抽象设备文件为fbcon.c,在这个目录下还有与各种显卡驱动相关的源文件。 1. 分析Framebuffer设备驱动。 FrameBuffer设备驱动基于如下两个文件: (1) linux/include/linux/fb.h (2) linux/drivers/video/fbmem.c 2. 分析这两个文件。

linux LCD驱动分析

Linux frambuffer设备总结 主要内容: 本文详细描述怎样编写linux frambuffer LCD 驱动程序 1. LCD 驱动/设备/控制器 2. linux frambuffer 驱动 2.1 为什么要用frambuffer? 2.2 什么是frambuffer设备? 2.3 怎样编写frambuffer驱动程序? 3. linux frambuffer 驱动源码分析 3.1 fb.h 3.2 fbmen.c 4. LCD 控制器驱动程序结构 4.1 为lcd显存分配内存 4.2 实现fb_ops 功能函数 1.LCD 驱动/设备/控制器 除了LCD设备的datasheet,还有两个关于LCD的非常不错的书,并且他们都是中文的。一本叫:《液晶显示技术》,另外一本叫《液晶显示器件》。这两本书详细介绍了LCD的知识,包括对硬件的操作,LCD的底层编程等。这两本书对设计LCD模块和底层编程都很有帮助。 2. linux frambuffer 驱动 2.1 为什么要用frambuffer? 如果我们的系统要用GUI(图形界面接口),比如minigui,MicroWindows.这时LCD设备驱动程序就应该编写成frambuffer接口,而不是编写成仅仅操作底层的LCD控制器接口。 2.2 什么是frambuffer设备? frambuffer设备层是对图像设备的一种抽象,它代表了视频硬件的帧缓存,使得应用程序通过定义好的接口就可以访问硬件。所以应用程序不需要考虑底层的(寄存器级)的操作。应用程序对设备文件的访问一般在 /dev 目录,如/dev/fb*。更多关于frambuffer设备的详细信息请阅读内核文档:linux /Documentation /fb /framebuffer.txt and linux /Documentation /fb /interal.txt 2.3 怎样编写frambuffer驱动程序? 关于如何编写frambuffer设备驱动,有很多参考资料。你可以在/https://www.doczj.com/doc/731534344.html, /HOWTO /index.html网站上阅读“Linux Frame buffer Driver Writing HOWTO”。 但是我认为这篇文章过于简短。所以分析内核相关部分的源码才是王道。 3.linux frambuffer 驱动源码分析 linux中frambuffer接口的所有功能实现都包括在下面两个文件中 1) linux/include/linux/fb.h 2) linux/drivers/video/fbmem.c

LCD驱动方式图解

LCD驱动方式图解 2006-4-10一、静态驱动 基本思想:在相对应的一对电极间连续外加电场或不外加电场。如图1所示; 驱动电路原理:如图2所示: 驱动波形: 根据此电信号,笔段波形不是与公用波形同相就是反相。同相时液晶上无电场,LCD处于非选通状态。反相时,液晶上施加了一矩形波。当矩形波的电压比液晶阈值高很多时,LCD处于选通状态。

二、多路驱动 基本思想: 电极沿X、Y方向排列成矩阵(如图4),按顺序给X电极施加选通波形,给Y电极施加与X电极同步的选通或非选通波形,如此周而复始。通过此操作,X、Y电极交点的相素可以是独立的选态或非选态。 图4、电极阵列 驱动X电极从第一行到最后一行所需时间为帧周期Tf(频率为帧频),驱动每一行所用时间Tr与帧周期的比值为占空比:Duty=Tr/Tf=1/N。 电压平均化: 从多路驱动的基本思想可以看出,不仅选通相素上施加有电压,非选通相素上也施加了电压。非选通时波形电压与选通时波形电压之比为偏压比Bias=1/a。为了使选通相素之间及非选通相素之间显示状态一致,必须要求选点电压Von一致,非选点电压Voff一致。为了使相素在选通电压作用下被选通;而在非选通电压作用下不选通,必须要求LCD的光电性能有阈值特性,且越陡越好。但由于材料和模式的限制,LCD电光曲线陡度总是有限的。因而反过来要求Von、Voff拉得越开越好,即Von/Voff 越大越好。经理论计算,当Duty、Bias满足以下关系时,Von/Voff取极大值。满足以下公式的a,即为驱动路数为N的最佳 偏压值。公式:。 LCD的动态驱动法 2006-3-14 摘要:本文以点阵式液晶显示器为例对其动态驱动法作以介绍,给出了一种克服交叉效应的办法。最后,给出了一款利用动态驱动法驱动码段式液晶显示器的实例。 关键词:液晶显示器具动态驱动法交叉效应 液晶的显示是由于在显示像素上施加了电场,这个电场是显示像素前后两电极上的电位信号的合成。由于直流电场容易使液晶的寿命降低,因此,一般都只建立直流成分非常小的交流电场。直流分量通常小于50mV。液晶显示器的驱动通过调整施

相关主题
文本预览
相关文档 最新文档