嵌入式系统用户接口设计之裸机界面开发

2019-12-11 18:15发布

本帖最后由 mcu_lover 于 2013-7-23 19:36 编辑

    裸机界面开发一般指在不借助于现成的GUI库的情况下,构建整个应用系统的图形(文本)用户接口。通常一个完整的GUI库都会提供诸如窗口(界面)管理,事件生成,派发等等。除此之外,其还有其固定的一个编程框架,通常这种框架因为GUI库的不同略有差异,但到目前为止,基本大同小异。这些框架大都提供好了各种图形液晶的驱动接口,按键/触摸屏的接口以及其它事件接口。通常利用GUI框架完成设计工作,就是在这种框架下,处理各种消息事件。可以说,利用GUI库,使得界面的开发工作相对的变得容易些。
    尽管GUI库提供了一个编程的框架,使得我们从繁杂琐碎的底层细节中脱离出来。但正如上面我们提及的,它仅仅只是是我们的工作变得相对容易些,而非轻而易举。有如下几个原因:
一是GUI库大都比较庞大,对于FLASH 和RAM 以及执行速度等资源均有一定的需求。因此很多中低端的MCU就基本无福消受。二则商业的GUI库大都售价不菲。最重要的一点是,界面逻辑的设计本来就是与具体的项目相关联,而每个项目的需求各异,进而导致界面的设计从来都不是一件轻而易举的事情,尤其是在要求系统界面可变性强的场合。
所以,很多场合下,我们不得不从零开始,设计整个界面的框架。也就是裸机界面开发。在这样的情况下,使用的显示装置一般有如下几种,字符型液晶,如1602 2002 2004 等等,图形点阵液晶如12832 12864 19264 240128 320240等等。这些图形点阵液晶,共同点就是单 {MOD},不需要显示复杂的图形界面。当然,复杂的图形界面在单 {MOD}上面,表现出来的效果也不是很理想。通常,在这些显示设备上,适当的使用直线,矩形,圆角矩形,以及反白显示,即可以实现不错的人机交互界面。
    因此,在这样的图形设备环境下,使用窗口的方式来构建整个界面是不合适的。相反,直接以屏幕(Screen)的方式来设计整个界面系统是比较合适的。那么,一个项目中的界面设计,就可以转化为设计合适的单个Screen ,然后想办法把这所有的单个Screen 连接起来,最终完成整个系统的界面开发工作。其实,Screen的方式在工控领域里面是使用的非常多的。因为工控领域要求开发可靠快速,对于界面的设计工作,一般是使用HMI触摸屏来实现。而HMI触摸屏设计就是以一个个 画面/屏幕 的方式来进行的。因为这种直接以画面/屏幕的方式来构建系统,是非常符合人的直观操作感受的。设想一下,如果你是一个设计者或者使用者,在操作带有屏幕显示的设备时候,肯定是在一个个屏幕界面下面进行的,如在设置屏幕界面进行系统的设置,在控制屏幕界面进行相关的控制工作等等。因此,作为一个设计者来说,在设计这样的系统的时候,务必要以面向屏幕的方式来思考整个用户界面工作的构建。可能会有人嗤之以鼻,整个GUI库里面均是以窗口的方式来组织界面的,为啥到这里就变成面向屏幕了呢。这是由于GUI库一般使用的场合下均含有较多的资源,如屏幕分辨率比较大, {MOD}彩位数高等等,且界面比较复杂,使用窗口的方式组织界面工作则较为方便。因此面向屏幕和面向窗口是针对不同的应用场合来说的。通俗一点来说,面向屏幕适合低端的单 {MOD}低分辨率图形设备环境(工控上的HMI除外),面向窗口则适合高端彩 {MOD}高分辨率的图形设备环境。
    回归到主题。既然我们要以面向屏幕的方式思考,那么首先我们需要将系统需求整理出来,然后将其归纳到一个个具体的屏幕中去。如主界面具体需要显示什么内容,设置界面有多少个,分别设置的内容是什么,控制界面有多少控制项等等。基本上只要系统需求明晰之后,系统需要的主界面,设置界面,控制界面内容等等均会随之而出,剩下的就是如何在相应的界面上,使得界面的显示看起来更具工业美感,操作上更加符合用户的操作习惯。对于我个人而言,我喜欢在纸上画出这些单个屏幕的内容,然后思考这些单个屏幕如何有效的连接在一起。然后用线连接这一个个屏幕。在线旁标注,是什么原因导致显示内容由当前屏幕跳转到另一个屏幕。如在主界面下,有四项相关系统参数显示,它们实时更新,以表征系统正在运行的某些变量。在主界面下当按下设定按键的时候,屏幕就会切换到设置界面,显示设置界面的相关内容。于是乎在主界面和设置界面之间的连线旁,我会标注 屏幕跳转事件为设置按键按下。这样,当所有屏幕之间跳转的关系确定好之后,基本上界面主体设计就完成了。如果你设计的最终界面,如同蜘蛛网一样混乱,各个屏幕之间均有联系,那么肯定你的设计是有问题的。好的设计应该是界面之间的跳转关系非常清晰,非常有层次感的。如果你没有达到此要求,试着重新组织你屏幕的内容,让每个屏幕所完成的工作,相对而言,具有一个整体性,这样经过多次重构之后,你的屏幕看起来一定非常有条理和层次感。就如同我们编程一样,为了追求结构上的优美,低耦合,高内聚的特性,总是需要对整个系统进行不断的抽象,重构,最终实现目标。当一个个屏幕设计出来之后,连接跳转关系也明确了之后,似乎一切都看起来轻松美好。是的,没错,但是有个前提,除非你接着看完本文后面的内容,否则,直到此处,一切还只是看起来美,镜中花水中月一般。好的建筑除了要优秀的设计图纸之外,还需要优秀的砖瓦匠去一砖一瓦堆砌。下面的内容,我们就来让每一个屏幕变得有血有肉,变得生动起来。
    对于一个具体的屏幕来说。从层次上来看,导致进入它的情况有两种,一种是上层屏幕跳转进入,也就是它的PARENT 屏幕,还有一种就是从下层返回回来,也就是它的CHILD屏幕。记住,这里的PARENT,CHILD是我们人为的将屏幕进行层次化分类的结果。如果不进行分类,所有的屏幕都是处于同一层次上。为什么要进行层次分类呢,就像之前在进行屏幕设计时候提到的那样,我们不断的进行抽象,就是为了让事情越来越简单。要知道,越抽象的东西,使用起来越简单。所以这里,为了方便屏幕的处理,我们就对屏幕进行了抽象,使得它们具有层次。所以对于某一个屏幕来讲,FROM_PARENT  和FROM_CHILD,分别表示从父屏幕跳转进入到本屏幕和从子屏幕返回到本屏幕。而从本屏幕返回父屏幕和进入子屏幕,则分别对应TO_PARENT 和TO_CHILD 两种情况。在这里,FROM_PARENT 和TO_CHILD 对应的其实是同一个事件。只是针对对象不一样角度不同而已。FROM_PARENT 是从本屏幕的角度来看,而TO_CHILD则是从父屏幕的角度来看。同理,TO_PARENT 和FROM_CHILD也是针对同一事件而言的。
history info.jpg (88.3 KB, 下载次数: 0) 下载附件 2013-7-23 19:34 上传

我们可以看到,最终它们对应的屏幕都是与具体的设置应用相关的。也许你会有疑问,如果我还有下一级菜单,不需要现在跳转到具体设置界面怎么办,没有关系,跳转到你想要的下一级菜单即可。不过是又多了一个屏幕而已。最终它们的目的地终究会是具体的某一个设置屏幕,或者信息查看屏幕。

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。