随着高性能嵌入式处理器的普及以及硬件成本的降低,特别是ARM系列处理器的不断推出,嵌入式系统的功能不断增强,嵌入式系统的应用领域也不断扩大。为了更好地操作系统,显示系统工作状况,需要使用液晶实时显示。然而在嵌入式系统的液晶驱动方面,不同的嵌入式硬件对应的驱动程序编写方法却千差万别。S3C2410X是三星公司生产的基于ARM920T内核的RISC处理器,主频高达203 MHz,内部集成了具有通用性的LCD控制器,支持STN和TFT液晶显示。
本文的研究内容源于一个正在开发的无线监控网络系统,该系统主要用来控制大田的灌溉,有3种工作方式:定时、定量和按逻辑条件工作,并能根据外在环境的变化做出相应的决策。同时,系统还能实时显示系统工作状况,并可以在系统界面上设置系统工作参数。为了实现该系统,采用合肥华恒公司生产的2410开发板作为主机,采用PD064VT5作为显示屏,分辨率为640×480。该显示屏采用18 b数据信号,能显示262 144色。本文从硬件和软件2个方面详细介绍液晶显示驱动程序的实现,给出了一种在Linux操作系统下编写液晶驱动的比较通用的方法。
1 系统硬件电路设计
1.1 LCD控制器
LCD控制器提供CPU应用处理机与被动(STN)或主动(TFT)平板显示器的接口,其主要功能是产生显示驱动信号,进而控制LCD的显示。在驱动LCD设计的过程中首先配置LCD控制器。在配置LCD控制器时需要正确的设置:显示方式(主动或被动显示)、显示类型(彩色或单色)、各种时钟信号、每行及每列的像点数以及每个像点的位数参数,然后则是帧缓冲区的指定,用户所要显示的数据都是从该缓冲区中读出,再显示到屏幕上的。随着技术的发展,现在的嵌入式处理器(片上系统)一般都集成LCD控制器,如本系统采用的ARM上就集成LCD控制器。集成LCD控制器的片上系统的基本体系结构如图1所示。
在图1中,处理器内核是整个片上系统的核心,如本系统的ARM内核。系统总线是指处理器内部的总线,如ARM著名的AMBA总线,其他片上系统的外设都通过总线和处理器连接。在LCD控制器工作时,通过DMA请求占用系统总线,直接通过SDRAM控制器读取SDRAM中指定地址(显示缓冲区)的数据。此数据通过LCD控制器转换成液晶屏扫描数据的格式,驱动液晶屏显示。这种模式是集成了LCD控制器的嵌入式处理器普遍使用的方式,其优点是:通过利用系统的SDRAM控制器,使显示缓冲和系统共享RAM空间,处理器可以直接读/写显示缓冲区;节省额外的显示缓存控制器和昂贵的显示缓存。
1.2 S3C2410X内部LCD控制器管脚
S3C2410X具有内置的LCD控制器,该控制器提供如下外部接口信号:
VFRAME:LCD控制器和LCD驱动器之间的帧同步信号。它通知LCD屏新的1帧的显示,LCD控制器在一个完整帧的显示后发出VFRAME信号。
VLINE:LCD控制器和LCD驱动器之间的线同步脉冲信号,它用于LCD驱动器将行移位寄存器的内容传送给LCD屏显示。LCD控制器在整行数据移入LCD控制器后,插入一个VLINE信号。
VCLK:LCD控制器和LCD驱动器之间的像素时钟信号。由LCD控制器送出的数据在VCLK的上升沿处送出,在VCLK的下降沿处被LCD驱动器采样。
VM:LCD驱动器的AC信号。VM信号被LCD驱动器用于改变行和列的电压极性,从而控制像点的显示或熄灭。VM信号可以与每个帧同步,也可以与可变数量的VLINE信号同步。
VD[23:0]:视频数据信号。PD064VT5是一个具有31管脚的液晶屏,根据工作方式的不同有不同的连接方式,图2是该液晶屏工作在分辨率为640×480时与S3C2410X的连接图。
1.3 S3C2410X内部LCD控制器
LCD控制器由REGBANK,LCDCDMA,VIDPRCS,TIMEGEN和LPC3600组成,如图3所示。REGBANK有17个可编程寄存器组和256X16的调色板存储器,用来设定LCD控制器。LCDCDMA是一个专用DMA,自动从帧存储器传输视频数据到LCD控制器,用这个特殊的DMA,视频数据可不经过CPU干涉就显示在屏幕上。VIDPRCS接收从LCDCDMA来的视频数据并在将其改变到合适数据格式后经VD[23:0]将之送到LCD驱动器,如4/8单扫描或4双扫描显示模式。TIMEGEN由可编程逻辑组成,以支持不同LCD驱动器的接口时序和速率的不同要求。TIMEGEN产生VFRAME,VLINE,VCLK,VM信号等。
1.4 S3C2410X内部LCD控制寄存器
S3C2410X的LCD控制器内有5个寄存器,分别为LCDCON1,LCDCON2,LCDCON3,LCDCON4,LCDCON5。这些寄存器的设置可以参见参考文献[2]。在本系统中,液晶屏PD064VT5的相关时间时间参数以及时序图分别如表1和图4所示。为了使液晶屏正确显示,需要相应的设定寄存器的值。为此,得到如下关键参数:
HSPW=96 HBPD=48 HFPD=16 VSPW=2
VBPD=33 VFPD=10 CLKVAL=4
同时将PNRMODE设为3,表示所用模块是TFT型;BPPMODE设为12,表示采用16 bpp输出,选择FRM565视频输出数据的格式。
2 系统软件设计
本系统中,采用的操作系统内核版本为2.4.20-8,并采用北京飞漫公司的MINIGUI软件进行系统界面的开发。由于在Linux2.2.XX之后内核版本中出现了一种驱动程序接口帧缓冲(Frame Buffer),因而LCD设备的驱动程序必须采用Linux的帧缓冲设备来处理与LCD控制器的底层命令。
帧缓冲设备对图像硬件设备进行抽象化处理,使应用软件可以通过定义明确的界面访问图像硬件设备,从而使软件无需了解涉及硬件底层驱动的细节就可以直接对显示缓冲区进行读写和I/O控制等操作。在通常情况下,驱动程序都为应用程序提供了专门的设备节点来访问该设备,如:/dev/fb0。用户可以将它看成是显示内存的一个映像,将其映射到进程地址空间之后,就可以直接进行读写操作,而读写操作可以立即反应到LCD上。同时Linux支持多个帧缓冲设备,最多可达32个,即/dev/fb0~/dev/fb31,其主设备号都为29,次设备号分别对应与0~31,缺省情况下的帧缓冲设备是/dev/fb0。
帧缓冲的实现分为2个方面:对LCD及其相关部件的初始化;对画面缓冲区的读写,具体到代码为read,write,lseek等系统接口的调用。基于帧缓冲的完整驱动程序就是以上两方面的实现。由于在Linux的发布版本中,包含了大量的设备驱动程序源代码,例如drivers/video下提供了多种显示卡的帧缓冲驱动程序,这就省去了上层接口调用程序的工作,只需要针对所用的LCD模块的类型以及接口时序,修改驱动程序中与底层相关的内容,即可得到自己的驱动程序。
与Linux的帧缓冲相关的代码在linux/drivers/video下,打开该路径后在目录下有一个名为S3C2410fb.c的文件,这个文件就是支持S3C2410X的帧缓冲驱动源文件,同时其定义了与底层相关的参数。根据上面对LCD控制器的分析结果,将该文件修改如下:
将修改后的驱动程序加入内核,然后重新编译内核。将新编译的Linux内核映像文件烧写到FLASH中,然后重新启动系统,就可以在LCD屏幕上显示图片以及图形界面。系统运行效果如图5所示。
3 结语
本文对S3C2410X的LCD内部控制器及其管脚做了详细的介绍,并给出具体的硬件连接图。同时也详细介绍Linux的驱动原理,并给出相应的软件实现。经过上述方法实现的设备驱动程序,可以很好地显示本系统中的示例程序,在系统中稳定的运行。如需要改变液晶显示器的型号,只要根据具体的液晶要求,搭建相应的硬件实现电路,然后根据上面的介绍,编写相应的驱动显示程序,修改相应的寄存器参数,即可很成功地点亮你所选择的液晶屏.