微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > MCU和DSP > 嵌入式系统的人机界面原型设计策略

嵌入式系统的人机界面原型设计策略

时间:02-19 来源:电子工程专辑 点击:
在目标硬件完成之前实现对人机界面的仿真,需要设计工程师在PC机上用软件构建人机界面原型。本文针对构建人机界面原型时所采用的工具语言和代码编写风格,以及不同语言编写的文件之间的接口问题进行了分析,对仿真设计人员有较好的指导作用。

构建一个人机界面原型能够帮助设计工程师在设计早期理解接口对设计的要求和接口的可用性。下面将探讨一种当目标硬件还远未实现时,在PC机上构建人机界面原型的方法。构建这类原型的主要目的有二。

1. 使同一个设计组中的其他成员能够看到该设备的工作过程。当我们在纸上设计一台交互式设备时,要判断设计中所描述的交互性能否实际实现,需要很大的想象力。而如果构建一个工作原型,就会使情况清晰许多,并且允许更多的旁观者来评论正在计划中的接口设计得怎样。很多时候,用接口原型进行试验,还能帮助设计工程师决定真正设计出的硬件需要多少按钮、多少LED、多少数字显示器或文本显示器。

2. 当硬件没有工作时,利用接口原型来为人机界面编写软件。为达到这一目的,出现在PC显示器上的接口原型必须采用C、C++或者其它适用于嵌入式开发的语言来控制。对于其它部分,则可以假设C是用于最终目标硬件的语言。

然后大概考虑一下需要仿真的是哪部分软件。在最简单的情况下,软件可用来打开或关闭一个LED,或者向一个小型字符显示器输出一个字符串。控制人机界面上的物理元件只是一项很普通的功能,所以能够在PC机上编写这种软件的优点是微不足道的。因为开关一个LED可能只需要一行代码,在一个LCD文本显示器上显示一个文本字符串也只需要调用一个10行或20行的函数。

真正困难的是如何编写软件来决定究竟是打开LED还是关闭LED,以及决定显示什么字符串。例如,当一个被测传感器的值持续超过警戒线一段时间,而一组使警戒有效的条件也满足了之后,软件也许应选择打开LED。再如,当用户按下一个按钮来选择菜单中的下一项时,软件也许应查阅一个描述该菜单的字符串表和操作表,以决定下一个显示的应该是哪一项。这种控制菜单之类的软件,其代码长度就会超过底层软件。

在本例中,我们的目的是编写一个文本显示和LED控制的仿真软件,以表示PC机屏幕的变化。我们可以编写警戒检查代码和菜单控制代码,使其既能运行在PC机上,又能运行在目标设备上。

这种仿真的方法并不新颖。但在为诸如PDA和游戏机之类并没有自己的开发环境的目标设备上编写软件时,通常需要用到这种方法。

编写仿真软件所需的工具

用Visual Basic在PC机上显示几个按钮和两行文本并不困难,但当将该原型与C代码接口时,就会显得十分麻烦。

如今有许多针对嵌入式开发的原型编写工具,用这些工具往往会迫使设计工程师依赖于它们的事件模型,从而导致设计过多地依赖这些工具。如果设计工程师遵从它们的接口设计风格,那么这些工具确实可以产生代码,但它们并不是对所有平台都具备足够的灵活度,而且它们产生的代码可能并不适合小型的微控制器。

我所采用的工具是Borland C++(后面将简写为CPB)。Borland C++并不是专门配合嵌入式系统的软件编写工具,但我发现它非常适合设计的需要,而且采用Borland C++不会将设计束缚在任何一个处理器或者任何一种软件结构上。

CPB中有一组预定义的图形组件,其中大多数并非针对嵌入式项目,而是针对桌面应用(类似下拉菜单)。但还是有一个小的子组件可用于我们本文所述的目的。象LED这样的UI元素就可以用图像来仿真。

CPB有三种版本:标准版、专业版和企业版。对于我们将要讨论的接口而言,标准版已经足够。

按钮、滑动块、标签和其它UI元素均可通过drag-and-drop环境插入一个表格(一个简单的对话窗口)中去。产生一个这样的表格就会生成一个C++类的框架。例如,每当用户点击一个图像或移动一个滑动块时,都会产生一组事件,而该表格中的每个元素都有这样一组事件与其对应。究竟需要对哪些事件作出反映则由程序员来选择。这些响应就被写成该表格所产生的类的成员函数。

如果前面板是由一个工业设计小组设计的,那么就会有整个显示图像可供利用。或者如果物理原型已经存在,那么一幅该物理原型的数字相片就可以用来作为背景。

我采用图像目标(在CPB内也叫作Timage)来显示大多数物理元件。因为采用了图像目标就可以引入位图,然后进行显示。例如可以引入一个发光二极管的图像。在该应用中,显示了一个包含5个按钮和4个LED的接口原图,如图1所示。背景图像中LED处于关断状态。一旦软件决定其中的一个LED应打开,那么这个发光LED图像的可见属性就被设为真,于是点亮的LED的图像就覆盖了不亮的LED图像。

有了这种简单的重叠多幅图像的诀窍,我们就可以仿真一个物理显示屏的其它部分。例如,假设我们采用CPB IDE来创建一个包含单词"ALARM"的标注,并将这一元素命名为AlarmIndicator,那么我们就可以编写一个函数来控制它:

void setAlarmState(Boolean state)

{

PanelForm->AlarmIndicator

->Visible = state;

}

面板表格中包含了我们仿真时所用到的所有图形对象。Alarm-Indicator就是我们将一个标签放到面板表格上之后为其分配的名字。当我们将该标签通过拖拽到表格窗口中的方式加入该表格时,它就成为了该表格的一个数据成员。

在CPB中,显示屏上的一个元素的所有属性都可以作为表征该元素的类的公共数据成员。因此,Visible属性只需进行一个简单的分配操作就能改变。公共数据成员可以在程序中的任何地方通过分配而改变。在CPB中,各属性也有其特殊状态,允许在IDE中通过该状态改变属性。开发者可以点击一个标注,并在属性窗口设置Visible属性。显示的颜色和字体也可以通过类似的方法改变。

现在来看一个setAlarmState()程序,该程序用于驱动基于CPB的仿真。以下代码为CPB专用代码,在最终的目标上无法运行。不用多久,我们将不得不为目标接口编写该函数的另一个版本,形式如下:

void setAlarmState(Boolean state)

{

if (state)

{

ledRegister |= 0x02;

}

else

{

ledRegister &= ~0x02;

}

}

有时,编程的风格会导致一些小函数造成函数调用开销。在较小的系统中这一问题较受关注,而这些函数中有一些可以写成宏或者内联(inline)函数。我通常只在项目的最后阶段才开始进行这类优化。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top