版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、S3C2440A 下彩色液晶显示器的设计嵌入式系统已成为当今最热门的概念之一 , 对大多数嵌入式系统开发者而言 , 显示系统 的硬件和软件开发是不可回避的关键性技术。三星公司开发的 S3C2440A 是一款以 ARM920T 为内核的嵌入式微处理器 ,它的最高工作频率达 533MHz, 内含 3 通道的异步串 行口 ,USB 主、从单元设备接口 ,摄像头接口 ,触摸屏接口 ,LCD 控制器等众多片上外设接口 , 且具低功耗、高性能 ,广泛适用于 PDA 、便携式媒体播放器、手持式导航仪等领域。目前国 内对该款高性价比嵌入式微处理器的开发应用才起步不久。夏普公司生产的 LCD 屏 LQ035Q7
2、DH01 为 3.5in 透反射式 TFT-LCD 显示器 ,屏幕分 辨率为320X 240,能提供262144 种色彩,显示亮度达到100nit,使设计人员能够在各种照 明条件下利用它来生动地展示图像和文字信息。 本文以 S3C2440A 和 LQ035Q7DH01 为 硬件基础 ,设计了显示硬件电路。软件平台采用 Linux 2.4.20, 交叉编译器为 arm-linux-gcc 2.95.3, 完成了对 LQ035Q7DH01 显示屏的驱动程序开发。以三星公司的嵌入式微处理器 S3C2440A 和夏普公司 3.5inLCD 屏 LQ035Q7DH01 为基础 ,设计了显示硬件电路 ,介
3、绍了帧缓冲设备的处理机制及底层驱动的接口函数 ,针对本 显示系统给出了如何开发其 Linux 帧缓冲设备驱动程序。不论是显示硬件电路还是软件驱 动程序 , 都有很强的可移植性 , 可以方便地移植到不同的平台。1 显示系统硬件电路1.1 LCD 控制器电路LCD 控制器用来传输图像数据并产生相应的控制信号 ,S3C2440A LCD 控制器能支持 高达 4K 色 STN 屏和 256K 色 TFT 屏,支持 1024X 768 分辨率下的各种液晶屏 , 具有 LCD 专用 DMA 。 LCD 控制器产生的控制信号和数据信号主要有:? VFRAME : LCD 控制器和 LCD 驱动器之间的帧同步
4、信号 , LCD 控制器在一个完整 帧显示完成后插入一个 VFRAME 信号 , 开始新一帧的显示。? VLINE : LCD控制器和LCD驱动器之间的行同步信号 丄CD控制器在整行数据移入LCD驱动器后插入一个 VLINE信号。? VCLK : LCD控制器和LCD驱动器之间的像素时钟信号 ,由LCD控制器送出的数据在VCLK的上升沿处送出,在VCLK的下降沿处被LCD驱动器采样。? VM :数据输出使能信号,在VM信号跃变成高电平后行数据信号开始由LCD控制器输出至LCD驱动器,当VM信号跃变为低电平后数据输出停止。? 数据线:也就是 RGB信号线,S3C2440A LCD控制器有VD0:
5、23共24根数据线,数据格式不同,接线方式就不同。本文用的是RGB565方式,只需要16根数据线(红色5根,绿色6根,蓝色5根)。其数据线接线方式如表1所示:K i RLG13闘5 It握恪氏F韵就樋线藤廉齐丸9l?j 1,u12n104R7|45412JoN21(5fft有 用H53I0DC卅HIH1_-ii43210LCD控制器电路如图1所示:TOVMS2L6vF亘吒5 匝施 眦VD7 西2 dCU: A1H二 1*戈r1pIdRg-匸g三A8IVDO/GPCtVQI/GK9 VD2 GK10 VD3 GPCH VD1 GK12VP5 GPtlSVD6 GTtnVD7 Clf 1&VD21
6、/nSS0.GPDlSVD22/tiSSl/CPDBvDsi.-GpnnsEaiiDiVD20 CPfHS lISfiRl YDL& troil/USHRXDlVD1B/GPDI(VLP】(1IUVblT/GPM/SPilKJSllVDie/GPDfi/SPlMTSOlS3C2440AIS VD23朋 底1闻 V020T5 VDigR5T4v.;ffl I LCD柱制呂电路1.2时序和数据匹配电路由于S3C2440A 的LCD控制器与LCD屏LQ035Q7DH01在数据格式及显示时序上无法匹配,需要选用一种时序控制IC或者用CPLD(也就是通常所说的LCD伴侣芯片)来对不同数据格式的数据接口进
7、行映射。但CPLD面积较大、成本较高,因而通常只在需要对电路进行灵活配置的情况下才使用。本文时序控制IC选用夏普公司的LZ9FC22。该芯片专用于对TFT型QVGA屏幕(屏幕分辨率320 X 240)的LCD进行时序控制。这是一个 18bit(R6G6B6) 的控制器,由于本文采用的是 RGB565 16 位工作模式,所以将其输入引脚D-zIk.RKr19D V5vbljlsleg綿歎縉繆餾溜噩瀧激yrao 星 一岸虽目邑 W辛PS3JIiisaiJST门 o 1 2 3 4 5 c o 13 4 5t:4 DTKRK KKRG ng G G G G G r-3.5=_=laBh 対fe gj
8、x |17Ifi1.3多路电压产生电路LCD屏内集成有数字电路和模拟电路,需要外部提供数字电压和模拟电压。另外,为了完成数据扫描,需要TFT轮流开启/关闭。当TFT开启时,数据通过源极驱动器加载到显示电极,显示电极和公共电极问的电压差再作用于液晶实现显示,因此需要控制LCD的开启电压、关闭电压,以及加到公共电极上的电压 ,本系统采用松下公司生产的芯片LM1117DT-3.3 来产生LCD所需要的数字电压,采用美国MAXIM公司推出的有源矩阵液晶显示器电源芯片 MAX1664 来产生其他电压,MAX1664 内部集成有两个 DC-DC变换器,可以为小型TFTLCD提供高效的调节电压。LCD所需各
9、电压如表2所示:表2LCD屛所需盘虹压;5L产生方式名称鞫号产生方克1熬字电企VSIfD3.3V由芯片LM1H7DT-期 产生VSHA5V由 i&tt MAX 1464 产生樓开自电HEVDD(15V从芯片MAX16M产生的用 荒电压21.bV分压得葫握极关晰电压VEE-10V从芯片MAK1664严生公共电霍VCOM2.6V/-0.8V从芯片创产生LED背Jt电也VL12L6V曲芯片MAXI664产生團3 上糧电压戶生电越C3 LIsa-亠 十“审丫举6V多路电压产生电路如图 3所示1.4显示驱动和LQ035Q7DH01的接口电路显示驱动和LQ035Q7DH01的接口电路如图 4所示:2 曲导
10、龛能籍弄冀斃鸳 嶷雷百號罪上為竺毙石閃丸务壬空沁罡1 耗总1 .L C7-X.JijLHA rt*琴3hJl-.I;UJgf-&S2Li呂-JKrii3Ja 4 亚帝醪动和I ()350711 HOt的推“杞路1.5显示系统整体结构框图显示系统整体结构框图如图 5所示。S3C2440ALCD控制器1時 =时序1CLZ9FC22LLCDLQO3W7DHOIr电曲电路(MAX 164和LMlllTDT-a 3)图5显示系统结构框图2 Linux下的帧缓冲(frame buffer) 设备Linux下编写显示设备的驱动程序有两种方法:一种是把显示设备抽象成一般的字符设备,驱动程序的写法和一般的字符设
11、备驱动类似;第二种就是帧缓冲设备驱动程序的编写。由于第一种方法不规范,而且实现功能有限,故一般不提倡;而帧缓冲驱动程序比较简单,也容易 实现,因而在嵌入式系统里得到了广泛应用。帧缓冲设备是一个提供显示内存和显示芯片寄存器从物理内存映射到进程地址空间中的设备,是Linux为图形设备提供的一个抽象接口 ,它将显示设备抽象为帧缓冲区。 帧缓冲允 许上层应用程序在图形模式下直接对显示缓冲区进行读写操作。这种操作是抽象的、统一的。应用程序不必关心物理显存的位置、换页机制等等具体细节。帧缓冲设备属于字符设备,采用 文件层-驱动层”的接口方式。Linux内核include/fnux/fb.h中定义了帧缓冲设
12、备的驱动层接口fb_info 结构体,fb_info定义了当前工作的显示卡的状态和帧缓冲设备的操作函数,它仅对内核可见。文件fb.h中还定义了 fb_var_screeninfo(显示卡可变特性,这些特性在程序运行期间可以由应用程序动态改变) fb_fix_screeninfo(显示卡不可变特性,这些特性在硬件初始化时就被定义了,以后不得修改)、fb_cmap(RGB 颜色映射表)等结构体,帧缓冲设备驱动程序主要依靠这几个结构体工作。除了结构体fbnfo只能在内核空间访问外,其他三个结构体都可以在用户空间访问。Linux内核driversvideofbmem.c中定义了帧缓冲设备的文件层接口f
13、ile_operations 结构体,它对应用程序可见,结构体中功能函数 open()和release()不需要底层的支持.而 read()、write() 、mmap()则需要调用 fb_get_fix()、 fb_get_var() 、fb_set_var() 、fb_get_cmap 、fb_set_cmap()(这些函数位于结构体fb_info中指针fbops指向的结构体变量中)等与底层LCD硬件相关的函数的支持。另一个功能函数是 ioctl(),ioctl() 是设备驱动程序中对设备的 I/O 通道进行管理的函数 , 应用程序 通过 ioctl() 系统调用来调用 fb_get_fi
14、x() 、fb_get_var() 、 fb_set_var() 、 fb_set_cmap() 、fb_get_cmap() 等来获得和设置结构体 fb_info 中 fb_var_screeninfo 结构变量 var 、fb_fix_screeninfo结构变量 fix 和 fb_cmap 结构变量 cmap 等变量的信息。在 fbmem.c 中给出了 ioctl() 命令和 fb_info 中结构体 fb_ops 的成员函数的对应关系 如下:FBIOGET_VSCREENINFO fb_get_varFBIOPUT_VSCREENINFO fb_set_var FBIOGET_FSCR
15、EENINFO fb_get_fixFBIOPUTCMAP fb_set_cmapFBIOGETCMAP fb_get_cmap用户应用程序只需要调用 FBIOXXXX 来操作 LCD 硬件。文件 fbmem.c 中还定义了帧缓冲设备底层驱动的管理函数:register_framebuffer(struct fb_info 3 fb_info) unregister_framebuffer(struct fb_info 3 fb_info)帧缓冲设备在驱动层所要做的工作仅仅是对 Linux 为帧缓冲的驱动层接口 fb_info 进行 初始化 . 然后调用这两个函数对其注册或注销。 帧缓冲设备驱
16、动层接口直接对 LCD 设备硬件 进行操作 ,而 fbmem.c 可以记录和管理多个底层设备驱动。3 显示系统帧缓冲驱动的编写3.1 定义 LCD 控制器结构体前面已经说过 ,LCD 控制器的功能是传输图像数据并产生相应的控制信号来驱动 LCD 显 示器 ,驱动程序需要根据当前具体显示硬件的特性,通过读写一系列的 LCD 控制寄存器来完S3C2440A 的 LCD 控制器成设定显示器分辨率和显示数据的格式 ,设置控制信号时序 , 指定显示缓 中区地址等 ,从而 提供给显示设备合适的数据信号和控制信号。文中根据需要为struct s3c2440fb_mach_infou_long pixcloc
17、k; /*像素时钟频率 */u_char bpp; /*每像素需要的 bit 数 */u_short xres; /*u_short yres; /*显示器行分辨率 */显示器列分辨率 */u_char hsync_len; /*u_char vsync_len; /*行同步信号的长度 */帧同步信号的长度 */u_char left_margin;/*从本行图象数据输出结束到下一行的行同步信号开始之间的像素时钟数 */u_char right_margin; /* 数*/u_char upper_margin;/*效行数 */u_char lower_margin; /*从行同步信号结束到该
18、行的图象数据开始输出之间的像素时钟从本帧图象数据输出结束到下一帧的帧同步信号开始之间的无从帧同步信号结束到该帧图象数据开始输出之间的无效行数*/u_char sync;struct s3c2440fb_lcd_reg reg; /*S3C2440ALCD 控制寄存器结构体 */;LCD驱动程序通过定义一个 s3c2440fb_mach_info 结构变量并给该变量赋值来完成 控制器的初始化。3.2 编写结构体 fb_info 中 fb_ops 对应的成员函数 对于本嵌入式系统的实现 , 需要下列 5 个函数: static struct fb_ops s3c2440fb_ops= owner:
19、THIS_MODULE,/*THIS_MODULE 宏用来防止驱动模块在使用状态下被卸载fb_get_fix:s3c2440fb_get_fix, fb_get_var:s3c2440fb_get_var, fb_set_var:s3c2440fb_set_var, fb_set_cmap:s3c2440fb_set_cmap,中定义。;结构体 fb_ops 在 Linux 内核 include/linux/fb.h这些函数都是用来设置和获取驱动层接口 fb_info 结构体中的成员变量的 , 前文已提过 当应用程序对设备文件进行 ioctl 操作时会调用它们。对于 fb_get_fix()
20、和 fb_get_var() 应用程序传入的是 fb_info 中的结构变量 fix 和 var,fb_set_var() 函数则是对 var 变量进 行设置。同样 fb_get_cmap() 和 fb_set_cmap() 则是对结构变量 cmap 内容进行读取和设置。在这 5 个函数 中,fb_set_var()设置了显示设备的显示模式,是最重要的一个函数。文中根据需要为当前显示硬件定义一个专有结构体 s3c2440fb_info, 该结构体包括一个 fb_info 结构变量 , 及其它 与所选 LCD 硬件有关的所有参数 .因此结构体 fb_ops 中成员函数对结构体 fb_info 的
21、操作 实际上就是对结构体 s3c2440fb_info 的操作。该结构体定义如下: struct s3c2440fb_info struct fb_info fb; /* fb_info结构变量 */signed int currcon; /*当前终端控制台的序号 */u_int max_xres;/* 屏幕能显示的最大行分辨率 */ u_int max_yres;/*屏幕能显示的最大列分辨率 */struct s3c2440fb_lcd_reg reg;/*S3C2440A LCD 控制寄存器 */* 其他与 LCD 硬件有关的参数 */;结构体 fb_ops 中的成员函数流程相似 ,本文在
22、此仅给出函数 s3c2440fb_set_var() 的流 程图和程序代码。函数 s3c2440fb_set_var() 流程图如图 6 所示:static struct fb_ops s3c2440fb_ops=owner:THIS_MODULE,/*THIS_MODULE宏用来防止驱动模块在使用状态下被卸载 / fb_get_fix:s3c2440fb_get_fix, fb_set_var:s3c2440fb_set_var, fb_set_cmap:s3c2440fb_set_cmap,;结构体 fb_ops 在 Linux 内核 include/linux/fb.h 中定义。这些函数
23、都是用来设置和获取驱动层接口 fb_info 结构体中的成员变量的 , 前文已提过 当应用程序对设备文件进行 ioctl 操作时会调用它们。对于 fb_get_fix() 和 fb_get_var() 应用程序传入的是 fb_info 中的结构变量 fix 和 var,fb_set_var() 函数则是对 var 变量进 行设置。同样 fb_get_cmap() 和 fb_set_cmap() 则是对结构变量 cmap 内容进行读取和设置。在这 5 个函数 中,fb_set_var()设置了显示设备的显示模式,是最重要的一个函数。文中根据需要为当前显示硬件定义一个专有结构体 s3c2440fb
24、_info, 该结构体包括一个 fb_info 结构变量 , 及其它 与所选 LCD 硬件有关的所有参数 .因此结构体 fb_ops 中成员函数对结构体 fb_info 的操作 实际上就是对结构体 s3c2440fb_info 的操作。该结构体定义如下: struct s3c2440fb_info struct fb_info fb; /* fb_info结构变量 */signed int currcon; /*当前终端控制台的序号 */u_int max_xres;/* 屏幕能显示的最大行分辨率 */ u_int max_yres;/*屏幕能显示的最大列分辨率 */struct s3c244
25、0fb_lcd_reg reg;/*S3C2440A LCD 控制寄存器 */* 其他与 LCD 硬件有关的参数 */;结构体 fb_ops 中的成员函数流程相似 ,本文在此仅给出函数 s3c2440fb_set_var() 的流 程图和程序代码。函数 s3c2440fb_set_var() 流程图如图 6 所示:图 6 函数 s3c2440fb_set_var() 流程图函数 s3c2440fb_set_var() 程序如下:static int s3c2440fb_set_var(struct fb_var_scree ninfo *var,i nt con, struct fb_i nf
26、o *in fo)将显示模式读入结struct s3c2440fb_i nfo *fbi= (struct s3c2440fb_i nfo *)i nfo; /*构体 s3c2440fb_info*/struct fb_var_scree ninfo *dvar= get_c on_var(& fbi-fb,c on);int err;err= s3c2440fb_validate_var(var,fbi); /* if(err) /* 无效返回 */ return err;dvar-red=fbi-rgbrgbidx-red; /*/dvar-gree n=fbi-rgbrgbidx-gre
27、e n; dvar-blue=fbi-rgbrgbidx-blue; dvar-tra nsp=fbi-rgbrgbidx-tra nsp; display-var= *dvar;显示模式是否有效*/将显示参数写入结构体fb_var_scree ninfos3c2440fb_hw_set_var (dvar,fbi); /*设置RGB颜色信息,设置S3C2440A 的LCD控制寄存器*/ return 0;LCD 控制器和 s3c2440fb_info */分配 150K 字节大小的 LCD 显示缓冲将 fb 注册到内核 */在控制台显示安装显示驱动程序成功3.3 编写初始化函数初始化函数首先
28、初始化 LCD 控制器和结构体 s3c2440fb_info, 填充 s3c2440fb_info 中结构变量 fb_info 的成员变量 , 这些成员变量的参数值由 LCD 显示器厂商的手册获得。然后通过 consistent_alloc 函数分配一片连续的空间。显示系统 采用的LCD显示方式为320X 240,16 位彩色。需要分配的显示缓冲区为320 X 240 X 16/8=150k字节,缓冲区通常分配在片外SDRAM 中,起始地址和末地址保存在 LCD 控制器寄存器 LCDSADDR1 和 LCDSADDR2 里, 最后调用 register_framebuffer(&fbi-fb)
29、将 fb_info 结构变量 fb 登记入内核。初始化函数如下:int _init s3c2440fb_init(void)(struct s3c2440fb_info *fbi;int ret;fbi=s3c2440fb_init_fbinfo(); /*初始化ret=s3c2440fb_map_video_memory (fbi); /* 区 */if(ret) /* 出错返回 */if(fbi)kfree(fbi);return ret;s3c2440fb_set_var (&fbi-fb.var,-1,&fbi-fb);ret=register_framebuffer(&fbi-fb)
30、;/*if(ret) /* 出错返回 */if(fbi)kfree(fbi);return ret;printk (Installed S3C2440 frame bufferkn);/*/该宏用来管理自己被使用的计数,模块在被使用时,是不允MOD_INC_USE_COUNT;/*许被卸载的*/return 0;4驱动程序嵌入到内核驱动程序嵌入到内核有两种方式:一种是直接编译入内核,随Linux启动的时候加载;另一种是编译成模块,动态加载。如果要将其直接编译入Linux内核,则需要将源代码文件拷贝到Lin ux内核源代码的相应路径里,并修改Makefile 文件和con fig. in 文件,这种方法会增加内核的大小,而且不能动态卸载,不利于调试,所以目前一般推荐米用第二种方式,如果这样,在本驱动程序的最后还需要加上宏module_i nit(s3c2440fb_i nit);这是告诉编译器该驱动程序的入口地址为初始化函数s3c2440fb_i ni t()。需要注意的是初始化函数必须在宏modulenit(s3c2440fb_i nit)使用前定义,否则会出现编译错误。而且在编译时至少要加上-D_KERNEL_ -DMODULE -DLINUX这几个参数,编译完成后通过 insmod 命令将驱动模块加载进内核,通过rmmod命令卸载驱动模
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论