一种用于嵌入式系统的液晶显示单元设计
扫描二维码
随时随地手机看文章
在自动化仪器仪表、工业测控装置等嵌入式计算机系统中,图形液晶显示模块(点阵LCD)以显示灵活、信息量大、可实现图形界面等优点而被广泛的用做显示终端。这些模块大多提供并行数据接口,少量提供串行接口的模块也要求通信采用特殊协议,给系统的软硬件设计都带来较大不便。在显示程序上,可移植通用的嵌入式图形用户界面GUI软件,如MiniGUI,OpenGUI等,以简化软件设计工作。但是,这些GUI软件移植繁琐,有些源代码不公开,一般需要数百KB的存储量,对于一些只要求实现简单界面的工控应用来说过于庞大,有一些功能(如鼠标操作、支持汉字输入法等)也不十分必要。
针对上述问题,本文结合LCD显示模块STN6448D-4K设计了一种满足工控要求的模块化图形液晶显示单元。硬件上通过51单片机搭建转换电路,实现模块并行访问时序到串行显示命令的转换。软件上结合串行接口命令和通信协议,用C语言编写了具有消息驱动机制的简单通用图形用户界面GUI程序,可以方便地移植到各种工控嵌入式系统。
1.标准串口扩展的设计
液晶显示模块STN6448D-4K支持640×480点阵4096伪彩色显示,用户接口为8位并行口。图1为模块的RS-232硬件扩展接口结构,在AT89C51单片机最小系统基础上,扩展了一片MAX232。单片机通过总线与模块STN6448D-4K的控制器相连。单片机接收并分析串口指令,调用相应函数完成对LCD的各种显示控制。为减少串行通信数据量,还扩展了一片2MB的Flash存储器AM29F016D,用于存储BMP图像和字符库、汉字库。通常采用的字库有汉字库文件Hzk16f.bin(16×16点阵)、Hzk24k.bin(24×24点阵),ASCII码文件ASC16.bin(16×8点阵)、ASC24.bin(24×12点阵)等,位图文件可以根据需要自行制作和增减。所有的字库和位图均通过RS-232接口从PC机下载到Flash存储器中,根据每个文件的存储首地址索引可以完成字符、汉字、位图的显示。
500)this.style.width=500;" border="0" />
2.串口指令和通信软件设计
按照STN6448D-4K的编程格式编写清屏、画点、画线、画矩形、写字符(ASCII字符、汉字)、加载位图等基本绘图函数的单片机程序比较简单,这里不作说明。单片机在完成初始化、清屏操作后,将就绪状态信息传递给嵌入式系统的CPU,并等待从RS-232传来的绘图指令。每一个绘图指令,都是一个绘图命令帧,与一个绘图函数相对应。
单片机收到一个完整的绘图指令后根据指令码识别不同的绘图操作,调用相应的函数完成显示控制。由于各个函数的指令长短不一,单片机需要判断出一条指令的结束;而且单片机完成LCD操作需要时间,硬件上又没有一个“BUSY”信号来指示单片机暂时不能接收指令。故程序设计上需保证传输同步和可靠性。
2.1 显示命令帧的封装
每一个绘图指令都封装成一个绘图命令帧,封装时依据以下3条规则:
(1)在每一个绘图指令的结尾加上标志字节END,封装成一个绘图命令帧。一个完整的绘图命令帧包括绘图指令码、绘图函数参数以及END标志。标志字节END的编码为0x55;
(2)在帧数据(指令的有效数据)中的某一个字节如果与END(0x55)相同,则将这个字节转换为(0xDE,0xCF)的2字节序列。其中0xDE称为转义字符TRANS,0xCF为数据与END标志相同时转义后的替换符TRANS_REP。
(3)如果帧数据中某个字节与转义字符(0xDE)本身相同,则将其更换为(0xDE,0xDE)2字节序列。
如果不考虑转义字符,一个完整的绘图命令帧格式如下:
500)this.style.width=500;" border="0" />
其中:CMD指令码,P1-Pn为n个字节数据。例如画水平线函数对应的命令帧中的字符依次为:0xCA, X0_H, X0_L, Y_H, Y_L, X1_H, X1_L, CLR。其中0xCA为指令码(对每个函数唯一),之后的6个为坐标参数,CLR为颜色。
2.2 接收状态机
单片机的接收中断处理采用接收状态机机制,状态转换如图2所示。
三个状态的含义为:
状态0: 准备接收一帧数据
状态1: 正在接收一帧数据,且上一次接收到的字节不是转义字符
状态2: 正在接收一帧数据,且上一次接收到的字节是转义字符
接收一个字节后,根据当前状态和接收到的字符a,进行状态转换,并舍弃转义字符等多余字节,将有效数据放入接收缓冲数组。当接收到有效的结束符END后,单片机将置缓冲满标志。单片机读到该标志,即可分析缓冲区中的数据,执行相应显示操作,并在操作后,清除缓冲满标志并向嵌入式系统的主CPU发出可以接收数据的应答字符(0x55)。
500)this.style.width=500;" border="0" />
3.图形用户界面(GUI)程序设计
前述设计已能满足简单的显示要求。在此基础上本文使用C语言编写了通用的GUI程序,设计出类VB的包含窗体和简单控件的界面,实现简单的可视化的操作:如按钮按压、文本输入、标签显示、选择框选择、软件菜单、窗体加载、位图显示、控件的Tab聚焦等。程序采用分层和模块化的思想,其分层结构如图3所示。这样,可以减少程序间的耦合,便于程序的完善和升级。
500)this.style.width=500;" border="0" />
3.1 逻辑设备层基本绘图函数(LD.C)
最底层的硬件设备层的绘图函数(HD.C)是显示命令帧的发送,采用液晶屏的绝对坐标(屏左上角为坐标零点)绘图,逻辑设备层的函数则是基于用户定义的当前“窗口”相对坐标(窗口左上角为坐标零点)绘图,窗口的位置任意。这里说的“窗口”就是当前显示的可操作范围,也称为“窗口上下文”。
绘图工具函数是一些内联函数和宏定义,创建当前的窗口上下文,完成绝对坐标与相对坐标相互转换,进行绘图元素的移动、复制,设置字间距、行间距等。基于窗口裁减的绘图函数调用各种绘图工具函数和硬件设备层的绘图函数,实现了点、线、汉字、字符、平面和3D矩形框的绘制,位图加载等,并将超出窗口范围的部分裁减掉(忽略不画)。
3.2 窗体/控件的设计
窗体(Form)和控件全部由结构体来定义。简单控件的共性是均为矩形框(平面的或3D的),所以都可以由公共结构体Gwidget加上各自的个性化属性和行为方式派生得到。控件属性(或状态)包括:按下/弹起(对Button控件)、聚焦/失去焦点、允许/禁止接受用户输入(区分Label和Text)等。基于GWidget可以派生Button、Label、Text、SelBox、menu等控件。Gwidget结构体成员包括“窗口”信息、控件ID(唯一标识一个控件)、控件属性/状态、控件边界宽度(实现3D显示)、默认的控件消息响应函数指针(如ButtonOnMsg)。
窗体(Form)既是一个独立的实体,又是控件的容器,用于管理属于它的所有控件并传递和响应消息。其结构体成员主要有:窗口上下文、消息响应函数指针、标题字符串指针、所含的控件数组指针、所含控件数、当前聚焦的控件ID等。
3.3 GUI消息响应机制
针对具体的应用要求,可以设计出各种各样的窗体(界面),每一个窗体包含多个控件。有的控件可以接受用户字符串和数字输入(Text控件)。这些窗体通过软件菜单组织起来。菜单为多叉树结构,最下一级菜单指向一个窗体或执行某个功能。同一级菜单包含并管理一个或多个菜单项。菜单结构体成员主要有:包含各菜单项的数组指针、菜单项个数、指向上级菜单的指针(可以为空)等,而菜单项结构体则包含指向下一级菜单的指针(可以为空)、指向一个窗体的指针(可以为空)、消息响应函数指针等。主程序和GUI之间的消息传递(或函数调用)机制如图4所示,虚线空心箭头指示消息的传递方向。
500)this.style.width=500;" border="0" />
4.结束语
本文设计的液晶显示单元具有RS-232接口,不仅在接入嵌入式系统方面提供了方便,也为在系统设计时,使用PC机并行地进行显示软件设计提供了途径。用C语言编写的GUI程序可以方便地移植到各种基于嵌入式操作系统的应用中,占用空间小,使用简单,通用性好,能满足一些较复杂界面显示的要求,其已经在笔者开发的多个嵌入式系统中得到应用。