一、LCD显示原理

利用液晶制成的显示器称为LCD,根据驱动方式可分为静态驱动、简单矩阵驱动以及主动矩阵驱动3种。当中,简单矩阵型又可再细分扭转向列型(TN)和超扭转式向列型(STN)两种,而主动矩阵型则以薄膜式晶体管型(TFT)为主流。

一块LCD 屏显示图像不但须要LCD驱动器,还须要有对应的LCD控制器。通常 LCD 驱动器会以 COF/COG的形式与LCD 玻璃基板制作在一起,而 LCD 控制器则由外部电路来实现。很多MCU 内部直接集成了LCD 控制器,通过LCD控制器能够方便地控制 STN 和 TFT 屏。

TFT屏是眼下入式系统应用的主流,下图给出了TFT屏的典型时序。时序图中的VCLK、HSYNC 和 VSYNC 分别为像素时钟信号(用于锁存图像数据的像素时钟)、行同步信号和帧同步信号,VDEN 为数据有效标志信号,VD 为图像的数据信号。

作为帧同步信号的 VSYNC,每发出一个脉冲,都意味着新的一屏图像数据開始发送。而作为行同步信号的 HSYNC,每发出一个脉冲都表明新的一行图像资料開始发送。在帧同步以及行同步的头尾都必须留有回扫时间。

下图给出了 LCD 控制器中应该设置的 TFT屏的參数,当中的上边界和下边界即为帧切换的回扫时间,左边界和右边界即为行切换的回扫时间,水平同步和垂直同步各自是行和帧同步本身须要的时间。 xres 和 yres 则各自是屏幕的水平和垂直分辨率,常见的嵌入式设备的 LCD 分辨率主要为 320*240、640*480 等。

二、帧缓冲

1、基本概念

帧缓冲(framebuffer)是 Linux 系统为显示设备提供的一个接口,它将显示缓冲区抽象,屏蔽图像硬件的底层差异,同意上层应用程序在图形模式下直接对显示缓冲区进行读写操作。用户不必关心物理显示缓冲区的详细位置及存放方式,这些都由帧缓冲设备驱动本身来完毕。对于帧缓冲设备而言,仅仅要在显示缓冲区中与显示点相应的区域写入颜色值,相应的颜色会自己主动在屏幕上显示。

帧缓冲设备为标准字符设备,主设备号为29,相应于/dev/fb%d 设备文件。帧缓冲驱动的应用很广泛,在Linux的桌面系统中,X windowserver就是利用帧缓冲进行窗体的绘制。嵌入式系统中的Qt/Embedded等图形用户界面环境也基于帧缓冲而设计。另外,通过帧缓冲可支持汉字点阵的显示,因此帧缓冲也成为Linux汉化的可行方案。

2、显示缓冲区与显示点

在帧缓冲设备中,对屏幕显示点的操作通过读写显示缓冲区来完毕,在不同的色彩模式下,显示缓冲区和屏幕上的显示点有不同的相应关系。下表各自是8位色和16 位色时显示缓冲区与显示点的相应关系:

3、Linux 帧缓冲相关数据结构与函数

1)fb_info 结构体

帧缓冲设备最关键的一个数据结构体是fb_info 结构体,它包含了关于帧缓冲设备属性和操作的完整描写叙述,这个结构体定义在/include/linux/fb.h中,代码例如以下所看到的:

该结构体记录了帧缓冲设备的所有信息,包含设备的设置參数、状态以及操作函数指针。每个帧缓冲设备都必须相应一个fb_info。

2)fb_ops结构体

fb_ops 的fb_check_var()成员函数用于检查能够改动的屏幕參数并调整到合适的值,而 fb_set_par()则使得用户设置的屏幕參数在硬件上有效。

3)fb_var_screeninfo和 fb_fix_screeninfo 结构体

fb_var_screeninfo记录用户可改动的显示控制器參数,包含屏幕分辨率和每一个像素点的比特数。fb_var_screeninfo 中的 xres 定义屏幕一行有多少个点, yres 定义屏幕一列有多少个点,bits_per_pixel 定义每一个点用多少个字节表示。而 fb_fix_screeninfo 中记录用户不能改动的显示控制器的參数,如屏幕缓冲区的物理地址、长度。当对帧缓冲设备进行映射操作的时候,就是从 fb_fix_screeninfo 中取得缓冲区物理地址的。上述数据成员都须要在驱动程序中初始化和设置。

fb_var_screeninfo和 fb_fix_screeninfo 结构体的定义在/include/linux/fb.h中,代码分别例如以下:

fb_fix_screeninfo结构体定义中第8 行的 visual 记录屏幕使用的色彩模式,在 Linux 系统中,支持的色彩模式包含例如以下几种。

●  Monochrome(FB_VISUAL_MONO01、FB_VISUAL_MONO10),每一个像素是黑或白。

●  Pseudo color ( FB_VISUAL_PSEUDOCOLOR 、FB_VISUAL_ST ATIC_PSEUDOCOLOR),即伪彩色,採用索引颜色显示。

●  T rue color(FB_VISUAL_TRUECOLOR),真彩色,分成红、绿、蓝三基色。

●  Direct color(FB_VISUAL_DIRECTCOLOR),每一个像素颜色也是有红、绿、

蓝组成,只是每一个颜色值是个索引,须要查表。

●  Grayscale displays,灰度显示,红、绿、蓝的值都一样。

4)文件操作结构体

作为一种字符设备,帧缓冲设备的文件结构体定义在/linux/drivers/vedio/fbmem.c文件里,代码例如以下:

帧缓冲设备驱动的文件操作接口函数已经在fbmem.c 中被统一实现,一般不须要由驱动project师再编写。

5)注冊与注销帧缓冲设备

Linux 内核提供了register_framebuf fer()和 unregister_framebu销帧缓冲设备,这两个函数都接受fb_info指针为參数,原型为:

对于register_framebuffer()函数而言,假设注冊的帧缓冲设备数超过了 FB_MAX(眼下定义为 32),则函数返回-ENXIO,注冊成功则返回 0。

三、Linux 帧缓冲设备驱动结构

Linux 帧缓冲设备驱动的主要结构例如以下图所看到的,帧缓冲设备提供给用户空间的file_operations 结构体由fbmem.c 中的file_operations 提供,而特定帧缓冲设备fb_info结构体的注冊、注销以及当中成员的维护,尤其是fb_ops中成员函数的实现则由相应的 xxxfb.c 文件实现,fb_ops 中的成员函数终于会操作 LCD 控制器硬件寄存器。

四、帧缓冲设备的用户空间訪问

通过/dev/fbns,应用程序可进行的针对帧缓冲设备的操作主要有例如以下几种。

●  读/写 dev/fbn:相当于读/写屏幕缓冲区。比如用cp  /dev/fb0 tmp 命令可将当前屏幕的内容拷贝到一个文件里,而命令cp  tmp  > /dev/fb0  则将图形文件tmp 显示在屏幕上。

●  映射操作:对于帧缓冲设备,可通过mmap()映射操作将屏幕缓冲区的物理地址映射到用户空间的一段虚拟地址中,之后用户就能够通过读/写这段虚拟地址訪问屏幕缓冲区,在屏幕上画图。并且若干个进程能够映射到同一个显示缓冲区。实际上,使用帧缓冲设备的应用程序都是通过映射操作来显示图形的。

● I/O 控制:对于帧缓冲设备,对设备文件的ioctl()操作可读取/设置显示设备及屏幕的參数,如分辨率、显示颜色数、屏幕大小等。

在应用程序中,操作/dev/fbn 的一般过程例如以下。

(1)打开/dev/fbn 设备文件;

(2)用 ioctl()操作取得当前显示屏幕的參数,如屏幕分辨率、每一个像素点的比特数和偏移;依据屏幕參数可计算屏幕缓冲区的大小;

(3)将屏幕缓冲区映射到用户空间;

(4)映射后就能够直接读/写屏幕缓冲区,进行画图和图片显示了。

样例:

功能:在LCD屏幕上显示红色汉字“赵”。

源代码例如以下:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h> int main()
{
int fbfd=0;
struct fb_var_screeninfo vinfo;
unsigned long screensize=0;
char *fbp=0;
int x=0,y=0;
fbfd=open("/dev/fb0",O_RDWR); //打开帧缓冲设备
if(!fbfd){
printf("error\n");
exit(1);
}
if(ioctl(fbfd,FBIOGET_VSCREENINFO,&vinfo)){ //获取屏幕可变參数
printf("error\n");
exit(1);
}
//打印屏幕可变參数
printf("%dx%d,%dbpp\n",vinfo.xres,vinfo.yres,vinfo.bits_per_pixel);
screensize=vinfo.xres*vinfo.yres* vinfo.bits_per_pixel/2; //缓冲区字节大小
fbp=(char *)mmap(0,screensize,PROT_READ|PROT_WRITE,MAP_SHARED,fbfd,0);//映射
if((int)fbp==-1){
printf("error\n");
exit(4);
}
memset(fbp,0,screensize); //清屏
char hz[16][2]={
0x08, 0x00, 0x08, 0x00, 0x08, 0x04, 0x7E, 0x84, 0x08, 0x48, 0x08, 0x28, 0xFF, 0x10, 0x08, 0x10,
0x28, 0x28, 0x2F, 0x28, 0x28, 0x44, 0x28, 0x84, 0x58, 0x00, 0x48, 0x00, 0x87, 0xFE, 0x00, 0x00,
}; //16*16字模库中提取的“赵”字相应的字符数组
int i,j,k;
for(j=0;j<16;j++){
for(i=0;i<2;i++){
for(k=0;k<8;k++){
if(hz[j][i]&(0x80>>k))
*((unsigned short *)(fbp + j*vinfo.xres*2 + i*16 + k*2))=0xf100;
}
}
}
munmap(fbp,screensize);
close(fbfd);
return 0;
}

ps:0xf100即相应16位:1111 1000 0000 0000,查看16位色时显示缓冲区与显示点的相应关系表,能够得出此像素点相应红色。

參考资料:《Linux设备驱动开发具体解释》

2014年6月23日星期一22时54分

LCD开发之汉字显示的更多相关文章

  1. 【STM32H7教程】第51章 STM32H7的LTDC应用之LCD汉字显示和2D图形显示

    完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第51章       STM32H7的LTDC应用之LCD汉字 ...

  2. 基于FPGA的LCD+CMOS视频采集显示使用小结

    基于FPGA的LCD+CMOS视频采集显示 液晶显示器采用扫描模式,RGB888 电源采用:+5V供电 usb供电有时候会出现供电不足的问题 显示器接口有两种选择:16bit或24bit  分别对应 ...

  3. STemwin汉字显示

    硬件环境: STM32F429,电容屏800X480 5点触控RGB屏幕 ,SPI flash: 软件环境: UCOSIII,STemwin: 汉字显示方法: 1.在SPIflash中装在字库XBF_ ...

  4. CozyRSS开发记录16-RssContentView显示

    CozyRSS开发记录16-RssContentView显示 1.RssContentView的布局和绑定 继续参照原型图来写xaml: 然后在RSSContentFrameViewModel里提供绑 ...

  5. Keil C51汉字显示的bug问题

    一.缘起 这两天改进MCU的液晶显示方法,采用“即编即显”的思路,编写了一个可以直接显示字符串的程序.如程序调用disstr("我是你老爸");液晶屏上就会显示“我是你老爸”. 二 ...

  6. Keil C51汉字显示的bug问题(0xFD问题)

    一.缘起 这两天改进MCU的液晶显示方法,采用“即编即显”的思路,编写了一个可以直接显示字符串的程序.如程序调用disstr("我是你老爸");液晶屏上就会显示“我是你老爸”. 二 ...

  7. C#的百度地图开发(四)前端显示与定位

    原文:C#的百度地图开发(四)前端显示与定位 有了这些定位信息,那要如何在前端的页面上显示出来呢?这需要用到百度地图的JavaScript的API.下面是示例代码. 前端代码 <%@ Page  ...

  8. Lcd(一)显示原理

    一.LCD控制原理 S5PV210处理器中自带LCD控制器,控制LCD的显示,把 LCD 图像数据从一个位于系统内存的 video buffer 传送到一个外部的 LCD 驱动器接口. 类型: STN ...

  9. iOS 9应用开发教程之显示编辑文本标签文本框

    iOS 9应用开发教程之显示编辑文本标签文本框 ios9显示.编辑文本 在iOS,经常会看到一些文本的显示.文字就是这些不会说话的设备的嘴巴.通过这些文字,可以很清楚的指定这些设备要表达的信息.本节将 ...

随机推荐

  1. 分散式-ubuntu12.04安装spark-1.0.0

    1. 安装文档: http://spark.apache.org/docs/latest/spark-standalone.html 2. web UI: master's web UI, which ...

  2. 汉字Collection

    只是上一行Demo private static string[] HanZis = new string[]{ "啊阿呵吖嗄腌锕爱矮挨哎碍癌艾唉哀蔼隘埃皑呆嗌嫒瑷暧捱砹嗳锿霭按安暗岸俺案鞍 ...

  3. 介绍一款替代SSMS的sqlserver管理工具 toad for sqlserver5.7

    原文:介绍一款替代SSMS的sqlserver管理工具 toad for sqlserver5.7 toad for sqlserver5.7 虽然SSMS很好很强大,不过有时候使用一些第三方工具可以 ...

  4. 试DG周围环境

    试DG周围环境 周围环境 名称 主库 备库 主机名 bjsrv shsrv 软件版本号 RedHat Enterprise5.5.Oracle 11g 11.2.0.1 RedHat Enterpri ...

  5. 恶意软件&quot;跨平台&quot; 小心钱包很受伤

    什么是跨平台攻击? 举例来说.就像网络诈骗犯为了避开电子商务平台的监控.会在微博上发消息.百度上撒网,腾讯上联系,最后在淘宝上交易.这样的跨平台操作的模式会大大添加犯罪过程监控和取证的难度.而跨平台攻 ...

  6. 第七章——DMVs和DMFs(2)——用DMV和DMF监控索引性能

    原文:第七章--DMVs和DMFs(2)--用DMV和DMF监控索引性能 本文继续介绍使用DMO来监控,这次讲述的是监控索引性能.索引是提高查询性能的关键性手段.即使你的表上有合适的索引,你也要时时刻 ...

  7. Spring 的@Scheduled注解实现定时任务运行和调度

    Spring 的@Scheduled注解实现定时任务运行和调度 首先要配置我们的spring.xml   ---  即spring的主配置文件(有的项目中叫做applicationContext.xm ...

  8. 王立平--Button底,点击效果设置

    1.新....xml <? xml version="1.0" encoding="utf-8"?>        <selector xml ...

  9. cocos2d-x3.0 lua学习(一个)

    最近开始学习Lua这里记录下一个写简单Lua代码,但我在写Lua代码.自己主动的代码提示的一些问题,谁希望提供下很好的解决方案,编辑我用SubLime Text2 test.lua.这里创建一个场景, ...

  10. HDU 3366 Passage (概率DP)

    Passage Problem Description Bill is a millionaire. But unfortunately he was trapped in a castle. The ...