S3C2440 LCD驱动(FrameBuffer)实例开发<一>

发布者:温馨的家庭最新更新时间:2024-07-17 来源: elecfans关键字:S3C2440  LCD驱动  FrameBuffer 手机看文章 扫描二维码
随时随地手机看文章

1. 背景知识

  1. 在多媒体的推动下,彩色LCD越来越多地应用到嵌入式系统中,PDA和手机等大多都采用LCD作为显示器材,因此学习LCD的应用很有实际意义!

  2. LCD工作的硬件需求:要使一块LCD正常的显示文字或图像,不仅需要LCD驱动器,而且还需要相应的LCD控制器。在通常情况下,生产厂商把LCD驱动器会以COF/COG的形式与LCD玻璃基板制作在一起,而LCD控制器则是由外部的电路来实现,现在很多的MCU内部都集成了LCD控制器,如S3C2410/2440等。TQ2440是采用了S3C2440,S3C2410通过LCD控制器就可以产生LCD驱动器所需要的控制信号来控制STN/TFT屏了。

  3. S3C2440内部LCD控制器结构图

clip_image002

根据数据手册来描述一下这个集成在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屏)

  1. 常见TFT屏工作时序分析:

clip_image002[12]

LCD提供的外部接口信号:

VSYNC/VFRAME/STV:垂直同步信号(TFT)/帧同步信号(STN)/SEC TFT信号;
HSYNC/VLINE/CPV:水平同步信号(TFT)/行同步脉冲信号(STN)/SEC TFT信号;
VCLK/LCD_HCLK:象素时钟信号(TFT/STN)/SEC TFT信号;
VD[23:0]:LCD像素数据输出端口(TFT/STN/SEC TFT);
VDEN/VM/TP:数据使能信号(TFT)/LCD驱动交流偏置信号(STN)/SEC TFT 信号;
LEND/STH:行结束信号(TFT)/SEC TFT信号;
LCD_LPCOE:SEC TFT OE信号;
LCD_LPCREV:SEC TFT REV信号;
LCD_LPCREVB:SEC TFT REVB信号。                                

VBPD(vertical back porch):表示在一帧图像开始时,垂直同步信号以后的无效的行数,对应驱动中的upper_margin;
VFBD(vertical front porch):表示在一帧图像结束后,垂直同步信号以前的无效的行数,对应驱动中的lower_margin;
VSPW(vertical sync pulse width):表示垂直同步脉冲的宽度,用行数计算,对应驱动中的vsync_len;
HBPD(horizontal back porch):表示从水平同步信号开始到一行的有效数据开始之间的VCLK的个数,对应驱动中的left_margin;
HFPD(horizontal front porth):表示一行的有效数据结束到下一个水平同步信号开始之间的VCLK的个数,对应驱动中的right_margin;
HSPW(horizontal sync pulse width):表示水平同步信号的宽度,用VCLK计算,对应驱动中的hsync_len;

   作为帧同步信号的VSYNC,每发出一个脉冲,都意味着新的一屏图像数据开始发送。而作为行同步信号的HSYNC,每发出一脉冲意味着新的一行图像资料开始发送。在帧同步和行同步的头尾留有回扫时间,这样的时序安排起源于CRT显示器电子枪偏转所需要的时间,但后来成为实际上的工业标准,因此TFT屏也包含了回扫时间。

   所有显示器显示图像的原理都是从上到下,从左到右的。这是什么意思呢?这么说吧,一副图像可以看做是一个矩形,由很多排列整齐的一行一行点组成,这些点称之为像素。那么这幅图在LCD上的显示原理就是:

A:显示指针从矩形左上角的第一行第一个点开始,一个点一个点的在LCD上显示,在上面的时序图上用时间线表示就为VCLK,我们称之为像素时钟信号;
B:当显示指针一直显示到矩形的右边就结束这一行,那么这一行的动作在上面的时序图中就称之为1 Line;
C:接下来显示指针又回到矩形的左边从第二行开始显示,注意,显示指针在从第一行的右边回到第二行的左边是需要一定的时间的,我们称之为行切换;
D:如此类推,显示指针就这样一行一行的显示至矩形的右下角才把一副图显示完成。因此,这一行一行的显示在时间线上看,就是时序图上的HSYNC;
E:然 而,LCD的显示并不是对一副图像快速的显示一下,为了持续和稳定的在LCD上显示,就需要切换到另一幅图上(另一幅图可以和上一副图一样或者不一样,目的只是为了将图像持续的显示在LCD上)。那么这一副一副的图像就称之为帧,在时序图上就表示为1 Frame,因此从时序图上可以看出1 Line只是1 Frame中的一行;
F:同样的,在帧与帧切换之间也是需要一定的时间的,我们称之为帧切换,那么LCD整个显示的过程在时间线上看,就可表示为时序图上的VSYNC

LCD控制器时序参数可以用下图形象的表示出来:

image

 

  1. 帧缓冲

     帧缓冲是Linux为显示设备提供的一个接口,它把一些显示设备描述成一个缓冲区,允许应用程序通过 FrameBuffer定义好的接口访问这些图形设备,从而不用去关心具体的硬件细节。对于帧缓冲设备而言,只要在显示缓冲区与显示点对应的区域写入颜色 值,对应的颜色就会自动的在屏幕上显示。

    通过帧缓冲显示汉字点阵,成为linux汉化的唯一可能性,帧缓冲设备是标准字符设备,主设备号为29,对应于/dev/fbn设备文件。

2. 帧缓冲(FrameBuffer)设备驱动结构

    帧缓冲设备为标准的字符型设备,在Linux中主设备号29,定义在/include/linux/major.h,但FB_MAJOR是在includelinuxfb.h中定义,次设备号定义帧缓冲的个数,最大允许有32个FrameBuffer,定义在/include/linux/fb.h中的FB_MAX,也就是最大支持显示器的个数。对应于文件系统下/dev /fb%d设备文件

3. 帧缓冲设备驱动在Linux子系统中的结构如下:

clip_image002[1]

    帧缓冲设备提供给用户空间的file_operations结构体由fbmem.c的file_operation提供,而特定帧缓冲设备结构体的注册、注销以及其中成员的维护,尤其是fb_ops中成员函数的实现则由xxxfb.c文件实现,fb_ops中成员函数最终会操作LCD控制器硬件寄存器。

4.  帧缓冲相关的重要数据结构

     从帧缓冲设备驱动程序结构 看,该驱动主要跟fb_info结构体有关,该结构体记录了帧缓冲设备的全部信息,包括设备的设置参数、状态以及对底层硬件操作的函数指针。在Linux 中,帧缓冲设备最关键的一个数据结构体是fb_info(为了便于记忆,我们把它简称为“FBI”),FBI中包括了关于帧缓冲设备属性和操作的完整描述。每一个帧缓冲设备都必须对应一个fb_info,fb_info在/linux/fb.h中的定义如下:(只列出重要的一些)

4.1 fb_info结构体

struct fb_info {

    int node;

    int flags;

    struct mutex lock;            /* 用于open/release/ioctl的锁*/

    struct fb_var_screeninfo var;/*LCD可变参数*/

    struct fb_fix_screeninfo fix;/*LCD固定参数*/

    struct fb_monspecs monspecs; /*LCD显示器标准*/

    struct work_struct queue;    /*帧缓冲事件队列*/

    struct fb_pixmap pixmap;     /*图像硬件mapper*/

    struct fb_pixmap sprite;     /*光标硬件mapper*/

    struct fb_cmap cmap;         /*当前的颜色表*/

    struct fb_videomode *mode;   /*当前的显示模式*/

 

#ifdef CONFIG_FB_BACKLIGHT

    struct backlight_device *bl_dev;/*对应的背光设备*/

    struct mutex bl_curve_mutex;

    u8 bl_curve[FB_BACKLIGHT_LEVELS];/*背光调整*/

#endif

#ifdef CONFIG_FB_DEFERRED_IO

    struct delayed_work deferred_work;

    struct fb_deferred_io *fbdefio;

#endif

 

    struct fb_ops *fbops; /*对底层硬件操作的函数指针*/

    struct device *device;

    struct device *dev;   /*fb设备*/

    int class_flag;    

#ifdef CONFIG_FB_TILEBLITTING

    struct fb_tile_ops *tileops; /*图块Blitting*/

#endif

    char __iomem *screen_base;   /*虚拟基地址*/

    unsigned long screen_size;   /*LCD IO映射的虚拟内存大小*/

    void *pseudo_palette;        /*伪16色颜色表*/

#define FBINFO_STATE_RUNNING    0

#define FBINFO_STATE_SUSPENDED  1

    u32 state;  /*LCD的挂起或恢复状态*/

    void *fbcon_par;

    void *par;    

};

其中,比较重要的成员有struct fb_var_screeninfo var、struct fb_fix_screeninfo fix和struct fb_ops *fbops,他们也都是结构体,下面我们一个一个的来看。


4.2 struct fb_var_screeninfo


    fb_var_screeninfo结构体主要记录用户可以修改的控制器的参数,比如屏幕的分辨率和每个像素的比特数等。例如:fb_var_screeninfo中的xres定义屏幕一行有多少个点,yres定义一屏幕一列有多少个点,bits_per_pixel定义每个点用多少个自己表示。该结构体定义如下:


struct fb_var_screeninfo {

    __u32 xres;                /*可见屏幕一行有多少个像素点*/

    __u32 yres;                /*可见屏幕一列有多少个像素点*/

    __u32 xres_virtual;        /*虚拟屏幕一行有多少个像素点*/       

    __u32 yres_virtual;        /*虚拟屏幕一列有多少个像素点*/

    __u32 xoffset;             /*虚拟到可见屏幕之间的行偏移*/

    __u32 yoffset;             /*虚拟到可见屏幕之间的列偏移*/

    __u32 bits_per_pixel;      /*每个像素的位数即BPP*/

    __u32 grayscale;           /*非0时,指的是灰度*/

 

    struct fb_bitfield red;    /*fb缓存的R位域*/

    struct fb_bitfield green;  /*fb缓存的G位域*/

    struct fb_bitfield blue;   /*fb缓存的B位域*/

    struct fb_bitfield transp; /*透明度*/   

 

    __u32 nonstd;              /* != 0 非标准像素格式*/

    __u32 activate;                

    __u32 height;              /*高度*/

    __u32 width;               /*宽度*/

    __u32 accel_flags;    

 

    /*定时:除了pixclock本身外,其他的都以像素时钟为单位*/

    __u32 pixclock;            /*像素时钟(皮秒)*/

    __u32 left_margin;         /*行切换,从同步到绘图之间的延迟*/

    __u32 right_margin;        /*行切换,从绘图到同步之间的延迟*/

    __u32 upper_margin;        /*帧切换,从同步到绘图之间的延迟*/

    __u32 lower_margin;        /*帧切换,从绘图到同步之间的延迟*/

    __u32 hsync_len;           /*水平同步的长度*/

    __u32 vsync_len;           /*垂直同步的长度*/

    __u32 sync;

    __u32 vmode;

    __u32 rotate;

    __u32 reserved[5];         /*保留*/

};

4.3 fb_fix_screeninfo结构体


     fb_fix_screeninfo结构体又主要记录用户不可以修改的控制器的参数,比如屏幕缓冲区的物理地址和长度等。当帧缓冲设备进行映射操作的时候,就是从fb_fix_screeninfo中取得缓冲区物理地址。该结构体的定义如下:


struct fb_fix_screeninfo {

    char id[16];                /*字符串形式的标示符 */

    unsigned long smem_start;   /*fb缓存的开始位置 */

    __u32 smem_len;             /*fb缓存的长度 */

    __u32 type;                 /*看FB_TYPE_* */

    __u32 type_aux;             /*分界*/

    __u32 visual;               /*看FB_VISUAL_* */

    __u16 xpanstep;             /*如果没有硬件panning就赋值为0 */

    __u16 ypanstep;             /*如果没有硬件panning就赋值为0 */

    __u16 ywrapstep;            /*如果没有硬件ywrap就赋值为0 */

    __u32 line_length;          /*一行的字节数 */

    unsigned long mmio_start;   /*内存映射IO的开始位置*/

    __u32 mmio_len;             /*内存映射IO的长度*/

    __u32 accel;

    __u16 reserved[3];          /*保留*/

};

4.4 fb_ops结构体


     fb_ops结构体是对底层硬件操作的函数指针,该结构体中定义了对硬件的操作有:(这里只列出了常用的操作)


struct fb_ops {

    struct module *owner;

    //检查可变参数并进行设置

    int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info);

 

    //根据设置的值进行更新,使之有效

    int (*fb_set_par)(struct fb_info *info);

 

    //设置颜色寄存器

    int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,

             unsigned blue, unsigned transp, struct fb_info *info);

 

    //显示空白

    int (*fb_blank)(int blank, 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);

 

    //图形填充

    void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);

[1] [2]
关键字:S3C2440  LCD驱动  FrameBuffer 引用地址:S3C2440 LCD驱动(FrameBuffer)实例开发<一>

上一篇:S3C2440中的GPIO
下一篇:S3C2440 ARM芯片时钟

推荐阅读最新更新时间:2024-11-17 10:45

基于S3C2440和DM9000移植LWIP(一)
使用mini2440已经有一段时间了。诸如裸机的LED,键盘开关等等等等也都试验过了,uCOS,WinCE也是浅尝了一下。如今想到了以太网。 由于mini2440的板上集成了一个DM9000的网卡,并且在CE系统里面成功的使用以太网与PC连接了。于是自然而然的想,能不能在uCOS下也实现以太网接口呢? 一上来什么都不懂,于是找一些资料,在这里要谢谢焦海波老师所著的嵌入式网络系统设计一书,移植过程中很多资料都来源于这本书。其次是mikenoodle的单片机驱动DM9000网卡一文,里面详细地讲述如何在2440裸机下驱动DM9000网卡。 首先明确我们需要做的事情是什么?为了实现在uCOS下的LWIP协议。我们当然需要一个LWIP协议
[单片机]
S3C2440 USB鼠标驱动(十九)
在上一章分析完USB总线驱动程序后,接下来开始写一个USB驱动: 本节目的:将USB鼠标的左键当作L按键,将USB鼠标的右键当作S按键,中键当作回车按键 参考/drivers/hid/usbhid/usbmouse.c(内核自带的USB鼠标驱动) 1、本节需要用到的宏如下: struct usb_device_id usbmouse_id_table =USB_INTERFACE_INFO(cl,sc,pr); USB_INTERFACE_INFO()设置usb_driver驱动的id_table成员 cl:接口类,我们USB鼠标为HID类,所以填入0X03,也就是USB_INTERFACE_CLASS_HID
[单片机]
<font color='red'>S3C2440</font> USB鼠标驱动(十九)
基于Linux和s3C2440的GPC控制器设计
  近年来,基于Internet的网络化控制系统已成为国内外测控领域研究的热点,在石油勘探开发、钢铁化工等领域有着广阔的应用前景。而控制器的设计和研发是整个网络控制系统的关键和核心。在一些地域高度分散以及环境恶劣的控制现场,使用嵌入式系统作为控制器节点,可更有利于多点分布式综合布控及并行处理,实现更好的测控效果。然而由于网络传输本身的特点,网络时延会不可避免地影响网络控制系统的控制性能和稳定性,因此本文提出基于S3C2440A及嵌入式Linux的GPC(Generalized PredictiveControl)控制器的设计方案,具有一定的通用性。    1 控制器硬件平台设计   控制器节点是嵌入式网络化测控系统的中心。
[嵌入式]
s3c2440中断总结+按键中断
一、启动代码之IRQ中断分析。 举例:timer4中断调用过程 1、当timer4发生中断,INTOFFSET寄存器的值变为中断源INT_TIMER4对应的值,即 14。 同时,程序将跳转到irq中断向量地址(0x18)处去执行,该处的指令为 b HandlerIRQ 2、在启动代码中有如下一段宏定义 $HandlerLabel HANDLER $HandleLabel $HandlerLabel sub sp,sp,#4 ;decrement sp(to store jump address) stmfd sp!,{r0} ;PUSH the work register to stack(lr does
[单片机]
<font color='red'>s3c2440</font>中断总结+按键中断
s3c2440裸机-LCD编程-1-LCD硬件原理
1.LCD示意图 下图是LCD示意图,里面的每个点就是一个像素点。 它里面有一个电子枪,一边移动,一边发出各种颜色的光。用动态图表示如下: 电子枪是如何移动的? 有一条CLK时钟线与LCD相连,每发出一次CLK(高低电平),电子枪就移动一个像素。 颜色如何确定? 由连接LCD的三组线RGB三原色混合而成:R(Red)、G(Green)、B(Blue)确定。 电子枪如何得知应跳到下一行? 有一条HSYNC信号线与LCD相连,每发出一次脉冲(高低电平),电子枪就跳到下一行,该信号叫做行同步信号。 电子枪如何得知应跳到原点? 有一条VSYNC信号线与LCD相连,每发出一次脉冲(高低电平),电子枪就跳到原点,该信
[单片机]
<font color='red'>s3c2440</font>裸机-LCD编程-1-LCD硬件原理
了解S3C2440触摸屏驱动的原理及其应用
一、开发环境 主 机:VMWare--Fedora 9 开发板:Mini2440--64MB Nand, Kernel:2.6.30.4 编译器:arm-linux-gcc-4.3.2 二、前提知识 1、Linux输入子系统(Input Subsystem): 在Linux中,输入子系统是由输入子系统设备驱动层、输入子系统核心层(Input Core)和输入子系统事件处理层(Event Handler)组成。其中设备驱动层提供对硬件各寄存器的读写访问和将底层硬件对用户输入访问的响应转换为标准的输入事件,再通过核心层提交给事件处理层;而核心层对下提供了设备驱动层的编程接口,对上又提供了事件处理层的编程接口;而事件处理层就为我们用
[单片机]
了解<font color='red'>S3C2440</font>触摸屏驱动的原理及其应用
GNU ARM汇编--(八)s3c2440的watchdog
从单片机起,watchdog就是必不可少的.在各种应用环境中,程序很可能跑飞或死掉,这时候就需要通过watchdog来保证整个系统重新恢复到正常状态. 照旧,给出s3c2440的datasheet说明: 概述: watchdog timer用于由于噪声或者系统错误引起的程序跑飞了的情况下恢复处理器的正常操作.它可以被用作一个可以请求中断服务的普通16bit的内部定时器.watchdog timer产生128 PCLK的重启信号. 特点: 有中断请求的普通内部定时器模式 当定时器计数为0(超时)时,产生内部的长达128PCLK周期的重启信号 watchdog timer的操作: F18-1显示wa
[单片机]
GNU ARM汇编--(八)<font color='red'>s3c2440</font>的watchdog
S3C2440裸机实验之timer(定时器)
S3c2440 有5 个16 位的定时器。定时器0、1、2、3 有脉宽调制功能(PWM)。定时器4有一个没有输出引脚的内部定时器。定时器0 有一个用于大电流设备的死区生成器。 定时器0 和1 共享一个8 位的预分频器(预定标器),定时器2,3,4 共享另一个8 位预分 频器. 定时器的时钟源为PCLK,首先经过预分频器降低频率后,进入第二个分频.可以生成5 种不同的分频信号(1/2,1/4,1/8,1/16 和TCLK) 定时器启动后,TCNTn开始减一计数,当TCNTn 等于TCMPn时, TOUTn 反转, TCNTn继续减数. 当TCNTn= 0 时, TOUTn 再次反转,并触发中断(中断已经使能). 若TCON
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved