资源描述
毕业设计(论文)
设计(论文)题目: 基于嵌入式Linux电表采集终端
显示模块设计与实现
学生姓名:
学生学号:
专业班级:
指导老师:
系主任(院长):
5 月 25 日
毕业设计(论文) 第 41 页
基于嵌入式Linux电表采集终端显示模块设计与实现
摘要
近年来我国电力需求不断增加,供应日趋紧张。为了保证电网安全、正确地商业化运营,必须有一套计量精确、功能强大的自动抄表系统。自动抄表系统节约了大量的人力和时间,快捷、准确地传递了信息,减少了人工抄表误差,提高了工作效率,是电力行业优化管理、走向市场的技术保障。
数据采集终端分为抄表模块,数据显示模块,控制模块,远程升级等。本文首先介绍了电表采集系统的总体设计,并通过比较现有嵌入式GUI,对电表采集系统的显示模块提出设计方案。随后阐述以ARM9为硬件平台,嵌入式Linux为软件平台,实现显示模块的两个前提条件:基于framebuffer显示屏驱动和特殊小键盘驱动的方法。最后在此基础上实现了一个适合电表采集终端工业应用的图形用户界面。
关键词:嵌入式Linux;framebuffer;Linux Device Driver;图形用户界面
The Design and Realization of Display Module of Automatic Meter Reading System
Abstract
In recent years, China's demand for electricity continues to grow, and increasingly in short supply. To ensure network security, the right to commercial operation, we must have a precise measurement, powerful automatic meter reading system. Automatic meter reading system will save a lot of time and manpower, efficient and accurate transmission of information, reduces manual meter reading errors, improve efficiency.
Data Collection Terminal is divided into meter reading module, data module, control module, remote upgrade module and so on. This paper introduces the meter collection system design framework, and proposes a design scheme of meter display module by comparing the existing embedded GUI. It then presents two foundational prerequisites: the framebuffer LCD driver and special keypad device driver with the ARM9 hardware platform and the embedded Linux software platform. Finally on this basis, we achieve a suitable acquisition interrupted meter industrial applications, graphical user interface.
Key words: Embedded Linux;framebuffer;Linux Device Driver;Graphical User Interface
目录
1. 绪论 1
1.1 课题背景及来源 1
1.2 课题研究的意义 1
1.3 论文结构 1
2.基于ARM的电表采集系统设计 3
2.1 总体设计原则 3
2.1.1 可靠性原则 3
2.1.2 实用性原则 3
2.1.3 智能化原则 3
2.2 基于ARM平台智能抄表终端 4
2.2.1 智能抄表系统的基本构成 4
2.2.2 系统硬件平台架构 5
2.2.3 LCD显示模块 5
2.2.4 嵌入式GUI的发展现状 6
3. Linux设备驱动 7
3.1 Linux设备驱动的概念 7
3.1.1 Linux设备驱动类别 7
3.1.2 Linux设备管理 7
3.2 framebuffer驱动 8
3.2.1 硬件介绍 8
3.2.2 LCD控制器 8
3.3 小键盘驱动 11
3.3.1 Linux键盘驱动概述 11
3.3.2 小键盘硬件描述 12
3.3.3 实现原理 12
4.电表终端显示模块的设计与实现 14
4.1 framebuffer驱动实现 14
4.1.1初始化 16
4.1.2 实现显示设备的主要操作。 16
4.1.3 加载LCD驱动 17
4.2 小键盘驱动实现 17
4.2.1 初始化 17
4.2.2 响应按键 18
4.2.3 转化按键扫描码 18
4.2.4 通用按键处理 18
4.3 图形引擎的设计 18
4.3.1 全局变量的定义 18
4.3.2 图形引擎初始化 19
4.3.3 基本图元设计 19
4.4 显示ASCII码点阵字符 23
4.4.1 点阵字符 23
4.4.2 定义ASCII码字模数组 24
4.4.3 显示字模 25
4.5 窗口显示设计 26
4.5.1 初始化 27
4.5.2 程序逻辑主体 33
4.5.3 释放资源 36
4.6 结果分析 37
4.6.1 设备驱动 37
4.6.2 图形界面 37
4.6.3 创新思想 37
总结 38
致谢 39
参考文献 40
1. 绪论
1.1 课题背景及来源
近年来我国电力需求不断增加,供应日趋紧张。为了保证电网安全、正确地商业化运营,必须有一套计量精确、功能强大的自动抄表系统。自动抄表系统不仅节约了大量的人力和时间,快捷、准确地传递了信息,减少了人工抄表误差,提高了工作效率,而且也是全面实现发、输、配电网用户电能量的自动采集、分析与计费功能的有效手段,是电力行业优化管理、走向市场的技术保障。
现今市场上使用的抄表系统大多采用单片机为平台,具有硬件功能单一,软件移植性差等缺点,因此不能满足智能抄表系统多用户挂接、远程信息传送、远程即时控制、远程软件升级、实时显示用户用电信息等需求。
1.2 课题研究的意义
后PC 时代,随着嵌入式系统的广泛应用,嵌入式操作系统也越来越受到重视。嵌入式操作系统具有结构小巧、实时性强、稳定性高等特点。嵌入式Linux为许多应用提供了良好的解决方案,其开放的源代码、强大的技术支持、良好的可扩展性及对众多硬件的支持都是它嵌入化的优势。电能表数据采集终端一般都挂接1~16 路电能表,实现对它们的轮流电量采集,将高性能的CPU 处理器和多任务操作系统应用于自动抄表系统中,结合嵌入式操作系统来实现新型的数据采集器,可以大幅度地提高系统整体性能。基于嵌入式Linux 的多任务机制,可以在多个进程调度下实现对电表的同时采集,处理速度大为提高,并且基于高速的处理器,可以连接大容量的SDRAM和FLASH,提高了系统的数据存储空间。为电力计量计费的准确、实时操作提供了可靠的技术保证。
典型的电力自动抄表系统主要由前端抄表子系统、通信子系统和中心处理子系统等3 部分组成。电能表数据采集终端是前端采集子系统的主要组成部分。
数据采集终端分为抄表模块,数据显示模块,控制模块,远程升级等。
1.3 论文结构
绪论部分概要介绍了本毕业设计课题的背景来源以及研究的意义。
第二部分介绍了抄表系统的总体设计原则,以及智能抄表系统实现的功能。
第三部分介绍了本课题研究需要的基础知识:Linux设备驱动,包括Linux设备驱的分类与特征。
第四部分首先分析了图形显示设备framebuffer驱动和人际交互设备特殊键盘驱动的设计方法,接着以此为基础,介绍了构建电表采集终端图形界面的设计思路和实现方法,最后阐述课题的难点、问题所在以及创新思想在本设计中的体现。
第五部分对研究工作进行归纳和总结。
2.基于ARM的电表采集系统设计
2.1 总体设计原则
2.1.1 可靠性原则
可靠性是智能抄表的基本要求。在实际使用要求系统具有抗恶工作环境的能力,无故障时间长。具体包括以下几个方面:
1. 电源系统的可靠性设计;
2. 结构坚固,不易损坏;
3. 电路的硬件及可靠性;
4. 软件的抗干扰和可靠性设计;
5. 系统故障的自保护、自检、自诊断设计;
6. 元器件与参数合理选择,老化筛选和部件、整体测试。
2.1.2 实用性原则
实用性是至关重要的,实用性是个综合性概念,它包括了产品的设计开发、生产销售和应用现场等诸多环节。对于一个民用产品实用性是首先必须考虑,否则设计得再好,也没有市场。主要有:
1. 系统生产的可行性,要求装配调试,装配方便;
2. 系统销售的可行性,要求性价比高,比国内、外同行有竞争力;
3. 系统应用的可行性,要求能适应现场各种工作条件,可靠性高,使用操作简单,维护方便。
2.1.3 智能化原则
智能化是抄表系统最大的特色之一。由于采用了微机系统,使系统具有数据处理,逻辑判断和信息存储的功能。在设计时,要选择性能先进、满足功能要求的CPU和足够容量的存储器,并提供良好的硬件环境,这样智能化才有了基础。智能抄表系统之所以能智能地处理问题,主要是软件的功劳。因此智能性原则必须充分发挥软件的作用,在设计中尽量采用软件来代替硬件完成一些功能,特别是数据采集过程的控制,故障的检测报警等。在设计中还从软件的角度,利用数据处理能力,数据存储能力、逻辑判断能力等特长去开发一些新功能。
智能另一表现是人机界面的友好性,要建立良好的人机界面。一方面要求系统能输出丰富的宜于读取的信息,另一方面要求人对机的信息通道畅通,即要求显示内容切换操作和参数设置简便,降低对操作人员知识要求,尽量实现“傻瓜型”人机界面[1]。
2.2 基于ARM平台智能抄表终端
2.2.1 智能抄表系统的基本构成
智能抄表系统根据数据采集方式的不同可以分为本地抄表系统和远程抄表系统。本地抄表系统主要采用手持式抄表终端,该手持抄表终端里面含有微控制器,配有外设如键盘、液晶显示屏等人机交互接口处理工作人员的命令,通过RS232接口通讯方式与电表进行数据传输,并将电表的相关数据显示在显示屏上。目前通用型智能抄表终端系统的结构框图如下图2.1所示。
智能抄表终端
挂接电表
PC
通讯网络
图2.1 智能抄表系统结构框图
1. 下层为挂接电表层:它规定了计量仪表的计量特性、数据项以及电气性能指标。
2. 中间层为数据传输协议层:规定了用户层与电表层之间以及相关设备进行数据交换的形式。
3. 最下层为用户层:它规定了电表能够为用户所提供的服务以及客户端与计量仪表进行数据交换的要求。
2.2.2 系统硬件平台架构
嵌入式抄表系统具有面向信息服务的特点,网络处理能力一直是系统设计的重点,在存储部分的硬件设计中考虑了网络接口、IDE接口等等的支持。同时为保持系统在接口上的可扩展性,系统预留出与网络、外部存储、各种板卡的接口,可使系统在功能上和性能上得到基本保障。硬件高效、稳定也是硬件设计的重点。
本系统采用了基于ARM9系统处理器的嵌入式商业级主板。ARM处理器专门用于处理娱乐、教育和商业设备。它是信息终端机、个人互联网访问设备等应用的理想处理器解决方案。ARM处理器在芯片上直接智能化地集成了各种关键的系统组件,例如LCD控制模块、USB和内存控制器等。最高主频可达180MHz,同时功耗极低。这种创新的集成功能可以提高系统的可靠性,降低系统整体成本,实现外型更加小巧的设计。
为运行Linux提供硬件上的支持,在开发板上还集成有64M的SDRAM、16M的串行Flash、以太网接口、串口、显示接口、I/O接口等。
2.2.3 LCD显示模块
LCD(液晶显示)模块满足了嵌入式系统日益提高的要求,它可以显示汉字、字符和图形,同时还具有低压、低功耗、体积小、重量轻和超薄等很多优点。随着嵌入式系统的应用越来越广泛,功能也越来越强大,对系统中的人机界面的要求也越来越高,在应用需求的驱使下,许多工作在Linux下的图形界面软件包的开发和移植工作中都涉及到底层LCD驱动的开发问题。因此在嵌入式系统中开发LCD驱动得以广泛运用。
本系统使用夏普微电子美国公司推出的3.5英寸透反射式(transflective)LQ035Q7DB02 TFT-LCD显示模块。该产品在传输模式下的亮度达到100cd/m2、对比度达100:1,提供262,144种色彩,功耗小于365mw,响应时间低于30ms,尺寸为65*86.2*4mm,重量为45g,能够在各种照明条件下利用它来生动地展示图像和文字信息,从而成为GPS系统、PDA及其它手持设备的理想选择[2]。
2.2.4 嵌入式GUI的发展现状
目前在嵌入式平台上可用的GUI产品比较丰富,但大体上可分为如下几类:
1. 各大嵌入式设备厂商依靠自己的能力开发的专用GUI产品;
2. 基于传统PC平台的风格和习惯移植的GUI产品,如Windows CE,QT Embedded,紧缩的X Window系统等;
这种GUI往往带有过多的PC平台痕迹,例如X Window系统本来是Linux以及其他类UNIX系统的标准GUI,基于服务器/客户端结构,适应面广,非常灵活方便。然而此类GUI通常无法满足嵌入式领域的低成本需求,其体积过于庞大,即使是紧缩的X Window系统,也需要占用800k字节以上的存储空间。
3. 专门定位于嵌入式平台的通用GUI产品,如Mini GUI,Micro Window等。
这种GUI的设计目标仍然是通用性。它们大多支持多窗口的随意切换、覆盖、以及可移动、可动态改变尺寸的窗口,诸如此类在多数嵌入式应用中几乎永远用不到的特性,使得应用程序的开发要考虑很多不必要的细节。
考虑到上述原因,一种较好的解决方案是自行设计一种轻型、适合电表采集终端要求的图形用户界面,显示功能齐全,操作简便,在应用、功能上都能满足用户需求,并且应大大降低成本。同时,它的响应速度也要有很大提高,进一步满足实时性要求[3]。
3. Linux设备驱动
3.1 Linux设备驱动的概念
3.1.1 Linux设备驱动类别
Linux将设备分为最基本的两大类:一类是字符设备,另一类是块设备。字符设备和块设备的主要区别是:在对字符设备发出读/写请求时,实际的硬件I/O一般就紧接着发生了。字符设备以单个字节为单位进行顺序读写操作,通常不使用缓冲技术;块设备则是以固定大小的数据块进行存储和读写的,如硬盘、软盘等,并利用一块系统内存作为缓冲区。为提高效率,系统对于块设备的读写提供了缓存机制,由于涉及缓冲区管理、调度和同步等问题,实现起来比字符设备复杂得多。LCD是以字符设备方式加以访问和管理的,Linux把显示驱动看作字符设备,把要显示的数据一字节、一字节地送往LCD驱动器。
3.1.2 Linux设备管理
Linux的设备管理是和文件系统紧密结合的,各种设备都以文件的形式存放在/dev目录下,称为设备文件。应用程序可以打开、关闭和读写这些设备文件,完成对设备的操作,就像操作普通的数据文件一样。为了管理这些设备,系统为设备编了号,每个设备号又分为主设备号和次设备号。主设备号用来区分不同种类的设备,而次设备号用来区分同一类型的多个设备。对于常用设备,Linux有约定俗成的编号,如硬盘的主设备号是3。Linux为所有的设备文件都提供了统一的操作函数接口,方法是使用数据结构struct file_operations。这个数据结构中包括许多操作函数的指针,如open()、close()、read()和write()等,但由于外设的种类较多,操作方式各不相同。struct file_operations结构体中的成员为一系列的接口函数,如用于读/写的read/write函数和用于控制的ioctl等。打开一个文件就是调用这个文件file_operations中的open操作。不同类型的文件有不同的file_operations成员函数,如普通的磁盘数据文件,接口函数完成磁盘数据块读写操作;而对于各种设备文件,则最终调用各自驱动程序中的I/O函数进行具体设备的操作。这样,应用程序根本不必考虑操作的是设备还是普通文件,可一律当作文件处理,具有非常清晰统一的I/O接口。所以file_operations是文件层次的I/O接口[4]。
3.2 framebuffer驱动
帧缓冲区是出现在Linux 2.2.xx及以后版本内核当中的一种驱动程序接口,这种接口将显示设备抽象为帧缓冲区设备区。帧缓冲区为图像硬件设备提供了一种抽象化处理,它代表了一些视频硬件设备,允许应用软件通过定义明确的接口来访问图像硬件设备。这样软件无须了解任何涉及硬件底层驱动的东西(如硬件寄存器)。它允许上层应用程序在图形模式下直接对显示缓冲区进行读写和I/O控制等操作。通过专门的设备节点可对该设备进行访问,如/dev/fb*。用户可以将它看成是显示内存的一个映像,将其映射到进程地址空间之后,就可以进行读写操作,而读写操作可以反映到LCD。
3.2.1 硬件介绍
LCD(液晶显示)模块满足了嵌入式系统日益提高的要求,它可以显示汉字、字符和图形,同时还具有低压、低功耗、体积小、重量轻和超薄等很多优点。随着嵌入式系统的应用越来越广泛,功能也越来越强大,对系统中的人机界面的要求也越来越高,在应用需求的驱使下,许多工作在Linux下的图形界面软件包的开发和移植工作中都涉及到底层LCD驱动的开发问题。因此在嵌入式系统中开发LCD驱动得以广泛运用。
本文硬件采用三星公司的S3C2410芯片的开发板,软件采用Linux 2.4.18平台,编译器为arm-linux-gcc的交叉编译器,使用夏普LQ035Q7DB02 TFT显示模块,在240×320分辨率下可提供16位彩色显示,通过对其Linux驱动程序进行改写和调试,成功地实现了对该种屏的驱动和显示。
3.2.2 LCD控制器
LCD控制器的功能是显示驱动信号,进而驱动LCD。用户只需要通过读写一系列的寄存器,完成配置和显示驱动。在驱动LCD设计的过程中首要的是配置LCD控制器,而在配置LCD控制器中最重要的一步则是帧缓冲区(framebuffer)的指定。用户所要显示的内容皆是从缓冲区中读出,从而显示到屏幕上的。帧缓冲区的大小由屏幕的分辨率和显示色彩数决定。驱动帧缓冲的实现是整个驱动开发过程的重点。S3C2410中的LCD控制器可支持STN和TFT两种液晶。对于STN 液晶平板,该LCD控制器可支持4位双扫描、4位单扫描和8位单扫描三种显示类型,支持4级和16级灰度级单色显示模式,支持256色和4096色显示,可接多种分辨率的LCD,例如640×480、320×240和160×160等,在256色显示模式时,最大可支持4096×1024、2048×2048和1024×4096显示。TFT液晶平板可支持1-2-4-8bpp(bits per pixel)调色板显示模式和16bpp非调色板真彩显示。
S3C2410 LCD控制器用于传输视频数据和产生必要的控制信号,如VFRAME、VLINE、VCLK、VM等。除了控制信号,S3C2410还有输出视频数据的端口VD[23:0],如图3.1所示。
Samsung
S3C2410X
LCD控制器
VCLK/LCD HCLK
VLINE/VSYNC/CPV
VFRAME/VSYNC/STV
VM/VDEN/TP
VD[23:0]
LEND
LCD-PWREN
LCDVF0
LCDVF01
LCDVF02
图3.1 S3C2410 LCD控制器
1. 寄存器介绍
LCD的寄存器主要有:LCDCON1寄存器、LCDCON2寄存器、LCDCON3寄存器、LCDCON4寄存器和LCDCON5寄存器。
2. 控制流程
REGBANK、LCDCDMA、VIDPRCS和LPC3600组成(如图3.2所示)。REGBANK有17个可编程寄存器组和256*16的调色板存储器,用来设定LCD控制器。LCDCDMA是一个专用DMA,自动从帧存储器传输数据到LCD控制器,用这个特殊的DMA,视频数据可不经过CPU干涉就显示在屏幕上。IDPRCS接受从LCDCDMA来的视频数据并在将其改变到合适数据格式后经VD[23:0]将之送到LCD驱动器,如4/8单扫描或4双扫描显示模式。TIMEGEN由可编程逻辑组成,以支持不同LCD驱动器的接口时序和速率的不同要求。TIMEGEN产生VFRAME、VLINE、VCLK、VM信号等。
REGBANK
TIMEGEN
VIDEO
MUX
LCDCDMA
VIDPRCS
LPC3600
VCLK/LCD-HCLK
VLINE/VSYNC/CPV
VFRAME/VSYNC/SYV
VM/VDEN/TP
LCDVF0
LCDVF1
LCDVF2
VD[23:0]
图3.2 S3C2410 LCD控制器内部方框图
3. 数据流描述
FIFO存储器位于LCDCDMA。当FIFO空或部分空时,LCDCDMA要求从基于突发传输模式的帧缓存器中来取来数据,存入要显示的图像数据,而这个帧存储器是LCD控制器在RAM中开辟的一片缓冲区。当这个传送请求被存储控制器中的总线仲裁器接受到后,从系统存储器到内部FIFO就会成功传送4个字。FIFO的总大小是28个字,其中低位FIFOL是12个字,高位FIFOH是16个字。S3C2410有两个FIFO来支持双扫描显示模式。在单扫描模式下,只使用一个FIFO(FIFOH)。
4. TFT控制器操作
S3C2410支持STN-LCD和TFT-LCD。TIMEGEN产生LCD驱动器的控制信号,如VSYNC、HSYNC、VCLK、VDEN和LEND等。这些控制信号与REGBANK寄存器组中的LCDCON1/2/3/4/5寄存器的配置关系相当密切,基于LCD控制寄存器中的这些可编程配置,TIMEGEN产生可编程控制信号来支持不同类型的LCD驱动器。
VSYNC和HSYNC脉冲的产生依赖于LCDCON2/3寄存器的HOZVAL域和LINEVAL域的培植。HOZVAL和LINEVAL的值由LCD屏的尺寸决定,见式(3.1)、(3.2):
HOZVAL = 水平显示尺寸 -1 (3.1)
LINEVAL = 垂直显示尺寸 -1 (3.2)
VCLK信号的频率取决于LCDCON1寄存器中的CLKVAL域。VCLK和CLKVAL域的关系如下,其中CLKVAL的最小值是0:
VCLK(Hz) = HCLK/[(CLKVAL+1)*2] (3.3)
帧频率是VSYNC信号的频率,它与LCDCON1和LCDCON2/3/4寄存器的VSYNC、VD-PD、VFPD、LINEVAL、HSYNC、HBPD、HFPD、HOZVAL和CLKVAL都有关系。大多数LCD驱动器都需要与显示器相匹配的帧频率,帧频率计算公式如下:
RATE = 1/{[(VSPW+1)+(VBPD+1)+(LINEVAL+1)+(VFPD+1)]*[(HSPW+1)+(HBPD+1)+(HFPD+1)+(HOZVAL+1)*[2*(CLKVAL+1)/(HCLK)]} (3.4)[5]
3.3 小键盘驱动
Linux由于其具有内核强大且稳定,易于扩展和裁减,丰富的硬件支持等诸多优点,在嵌入式系统中得到了广泛的应用。很多嵌入式Linux系统,特别是一些具有与用户强交互的嵌入式系统,往往需要配备一个特殊键盘,此时开发者需要根据实际情况,为自己的特殊键盘编写驱动程序。
3.3.1 Linux键盘驱动概述
Linux中的大多数驱动程序都采用了层次型的体系结构,键盘驱动程序也不例外。在Linux中,键盘驱动被划分成两层来实现。其中,上层是一个通用的键盘抽象层,完成键盘驱动中不依赖于底层具体硬件的一些功能,并且负责为底层提供服务;下层则是硬件处理层,与具体硬件密切相关,主要负责对硬件进行直接操作。键盘驱动程序的上层公共部分都在driver/keyboard.c中。该文件中最重要的就是内核用EXPORT_SYMBOL这个宏导出的handle_scancode函数。handle_scancode完成的功能是:首先将扫描码转换成键码,接着根据shift, alt等扩展键的按下情况将键码转换成目标码,一般情况下是ASCII码,最后将该ASCII码放到终端设备的缓冲区中,并且调度一个tasklet负责将其在显示器上回显出来。可以看出,这个函数完成的是键盘驱动程序中最核心的一些工作,而这些核心的逻辑功能是不依赖于底层硬件的,所以可以将其独立出来,并且导出给底层的硬件处理函数调用。在这个文件中还定义了其它几个回调函数,它们由键盘驱动程序中的上层公共部分调用,并由底层硬件处理函数实现。比如kbd_init_hw, kbd_translate, kbd_unexpected_up等等。其中kbd_translate由handle_scancode调用,负责将扫描码转换成键码;键盘驱动程序的底层硬件处理部分则根据不同的硬件有不同的实现。例如PC平台上标准键盘的底层硬件处理函数都集中在driver/pc_keyb.c中。这个文件包括了键盘中断处理函数keyboard_interrupt,扫描码到键码转换函数pckbd_translate等其他一些与底层硬件密切相关的函数。
在这种体系结构下,要添加一块特殊键盘到系统中就显得格外清晰。开发者只需为其编写驱动程序中的底层硬件处理函数,就可以将该键盘驱动起来。一般说来,底层硬件处理函数中最重要的工作就是在键盘中断处理中获取被按下键的扫描码,并且以它为参数调用handle_scancode,该扫描码可以自己定义,但它必须唯一地标识出被按下键在键盘上的位置。此外,开发者还需要提供对应的从自定义扫描码到键码的转换函数kbd_translate。具体的键码转换,将目标码放到终端的输入缓冲区,以及回显等工作都由handle_scancode负责完成。在此我们也可以看出,内核导出函数handle_scancode在整个键盘驱动程序中,起着将上层通用抽象层和底层硬件处理层粘和起来的关键作用。
3.3.2 小键盘硬件描述
本系统的构建选用了三星公司的S3C2410开发板作为硬件平台。特殊键盘的硬件模块是ZLG7289A芯片。ZLG7289A是广州周立功单片机发展有限公司自行设计的,具有SPI串行接口功能的可同时驱动8位共阴式数码管(或64只独立LED)的智能显示驱动芯片,该芯片同时还可连接多达64键的键盘矩阵,单片即可完成LED显示、键盘接口的全部功能。ZLG7289A内部含有译码器,可直接接收BCD码或16进制码,并同时具有2种译码方式,此外,还具有多种控制指令,如消隐、闪烁、左移、右移、段寻址等。
3.3.3 实现原理
在键盘产生按键动作之后,键盘上的扫描芯片获得键盘的扫描码,并将其发送到主机端。在主机端的处理过程为端口读取扫描码后,对键盘模式作一个判断,如果是RAW模式,则直接将键盘扫描码发送给应用程序;如果是其它模式,则就将扫描码转化成为键盘码,然后再判断模式以决定是否将键盘码直接发送给应用程序:如果是XLATE或Unicode模式,则将键盘码再次转化成符号码,然后根据对符号码解析,获得相应的处理函数,并将其送到TY设备的缓存中。模式判断的对应关系如下图所示:
键盘模式有4种,这四种模式的对应关系是:
Scancode mode(RAW)模式:将键盘端口上读出的扫描码放入缓冲区,通过参数s可以设置。
Keycode mode(MEDIUMRAW)模式:将扫描码过滤为键盘码放入缓冲区,通过参数k可以设置。
ASCII mode(XLATE)模式:识别各种键盘码的组合,转换为TTY终端代码放入缓冲区,通过参数a可以设置。
UTF-8 mode(Unicode)模式:Unicode模式基本上与XLATE相同,只不过可以通过数字小键盘间接输入Unicode代码,通过参数u可以设置。
4.电表终端显示模块的设计与实现
自20世纪80年代以来,随着液晶屏幕成本的降低,各种嵌入式图形消费产品和工业设备逐步获得了广泛的应用,从面向专业人员的高端产品逐步转变成为面向普通消费者和普通技术人员的低端产品。作为人机交互的纽带,图形用户界面(GUI)的重要性越来越凸现出来。考虑到实际应用的专用性以及消费类产品对成本的敏感性,由桌面PC操作系统演变来的Windows CE /QT Embedded等嵌入式操作系统所提供的GU I所要求的资源普遍较高。Mini GU I等GU I系统虽然专为嵌入式系统设计,但开发使用需要考虑较多琐碎的细节。因此本文从实际应用出发,在上文完成的framebuffer驱动和小键盘驱动基础上,开发了一套适合电表采集终端显示信息的图形界面。系统总体结构如图4.1所示。
framebuffer
小键盘
framebuffer,小键盘设备驱动
通用API
open
read
write
close
图形界面
图4.1 电表终端图形界面系统结构
4.1 framebuffer驱动实现
帧缓冲设备对应的设备文件是/dev/fb*。如果系统有多个显卡,Linux还支持多个帧缓冲设备,最多可达32个,即/dev/fb0~/dev/fb31。而/dev/fb则为当前缺省的帧缓冲设备,通常指向/dev/fb0。当然在嵌入式系统中支持一个显示设备就够了。帧缓冲设备为标准字符设备,主设备号为29,次设备号则从0到31。分别对应/dev/fb0~/dev/fb31。
帧缓冲设备采用“文件层-驱动层”的接口方式。在文件层为之定义了以下数据结构。
Static struct file_operations fb_fops={
ower: THIS_MODULE,
read: fb_read, /*读操作*/
write: fb_write, /*写操作*/
ioct1: fb_ioct1, /*I/O操作*/
mmap: fb_mmap, /*映射操作*/
open: fb_open, /*打开操作*/
release: fb_release, /*关闭操作*/
}
其成员函数都在linux/driver/video/fbmem.c中定义,其中的函数对具体的硬件进行操作,对寄存器进行设置,对显示缓冲进行映射。主要结构体还有以下几个。
struct fb_fix_screeninfo:记录了帧缓冲设备和指定显示模式的不可修改信息。它包含了屏幕缓冲区的物理地址和长度。
struct fb_var_screeninfo:记录了帧缓冲设备和指定显示模式的可修改信息。它包括显示屏幕的分辨率、每个像素的比特数和一些时序变量。其中变量xres定义了屏幕一行所占的像素数,yres定义了屏幕一列所占的像素数,bits_per_pixel定义了每个像素用多少个位来表示。
struct fb_info:Linux为帧缓冲设备定义的驱动层接口。它不仅包含了底层函数,而且还有记录设备状态的数据。每个帧缓冲设备都与一个fb_info结构相对应。其中成员变量modename为设备名称,fontname为显示字体,fbops为指向底层操作的函数的指针。
LCD驱动开发的主要工作包括如下三个步骤:
4.1.1初始化
初始化函数首先初始化LCD控制器,通过写寄存器设置显示模式和颜色数,然后分配LCD显示缓冲区。在Linux中可以用kmalloc()函数分配一段连续的空间。缓冲区大小为:点阵行数×点阵列数×用于表示一个像素的比特数/8。缓冲区通常分配在大容量的片外SDRAM中,起始地址保存在LCD控制寄存器中。本文采用的LCD显示方式为240×320,16位彩色,则需要分配的显示缓冲区为240×320×2=150kb。最后是初始化一个fb_info结构,填充其中的成员变量,并调用register_framebuffer(&fb_info),将fb_info登记入内核。
编写结构fb_info中函数指针fb_ops对应的成员函数,对于嵌入式系统的简单实现,只需要下列三个函数就可以了。
struct fb_ops{
…… int (*fb_get_fix)(struct fb_fix_screeninfo *fix, int con, struct fb_info *info);
int (*fb_get_var)(struct fb_var_screeninfo *var, int con, struct fb_info *info);
int (*fb_set_var)(struct fb_var_screeninfo *var, int con, struct fb_info *info);
……
}
struct fb_ops在include/linux/fb.h中定义。这些函数都是用来设置/获取fb_info结构中的成员变量的。当应用程序对设备文件进行ioctl操作时候会调用它们。对于fb_get_fix(),应用程序传入的是fb_fix_screeninfo结构,在函数中对其成员变量赋值,主要是smem_start(缓冲区起始地址)和smem_len(缓冲区长度),最终返回给应用程序。而fb_set_var()函数的传入参数是fb_var_screeninfo,函数中需要对xres、yres和bits_per_pixel赋值。
4.1.2 实现显示设备的主要操作。
读/写(read/write)/dev/fb:相当于读/写屏幕缓冲区。
映射(map)操作:由于Linux工作在内核保护模式,每个应用程序都有自己的虚拟地址空间,在应用程序中是不能直接访问物理缓冲区地址的。为此,Linux在文件操作 file_operations结构中提供了mmap函数,可将文件的内容映射到用户空间。对于帧缓冲设备,则可通过映射操作,可将屏幕缓冲区的物理地址映射到用户空间的一段虚拟地址中
展开阅读全文