目录
1 绪论 1
1.1 智能家居及其发展趋势 1
1.2 嵌入式系统与智能家居 1
1.3 图形用户界面与智能家居 2
2 硬件体系结构 4
2.1 开发板硬件资源 4
2.2 CPU-S3C44B0X 4
3 软件平台 6
3.1 VxWorks操作系统介绍 6
3.1.1 实时操作系统和分时操作系统的区别 6
3.1.2 VxWorks的特点 6
3.1.3 对一个实时内核的要求 7
3.1.4 VxWorks结构-Wind、组件 7
3.2 主机工具-Tornado 8
3.2.1 Tornado 概述 8
3.2.2 主机仿真与下载 10
4 图形硬件与图形库 14
4.1 S3C44B0X的LCD显示屏 14
4.2 触摸屏 15
4.3 图形库 WindML 15
5 图形驱动的实现 17
5.1 WindML仿真 17
5.1.1 WindML库配置编译 17
5.1.2 非标设备配置 18
5.1.3 非标设备配置320*240彩色LCD 18
5.2 汉字处理 19
5.2.1 BMF文件的结构 19
5.2.2 BMF文件的使用 20
5.2.3 中文英文混合显示 21
5.3 WindML for Arm 23
5.3.1 图形驱动 23
5.3.2 触摸屏驱动 27
5.4 图形库的使用 31
6 智能家居界面的设计与实现 34
总结 40
致谢 41
参考文献 42
附录 43
1.3图形用户界面与智能家居
智能家居系统围绕家庭智能中心(HIC)构建了家庭测控总线网络,并通过家居智能接口模块(IFU)完成电气匹配,实现了对各种家庭设备集中管理、分散控制、智能监测、接入路由、信息处理等诸多功能。其家庭智能核心由智能控制器(HIC)、家居智能系统人机交互终端(HLK)、综合配线箱等组成。本设计的目标就是充分依托系统的网络功能,开发家居智能系统人机交互终端。
图形用户界面是智能家居系统的重要组成部分之一。用控制安全系统的图形用户界面的软件(GUI)直接与视频切换主机连接,可以对整个系统进行全面控制和编程。通过一个优化界面与系统通讯,可以对其所有系统功能实现高性能的实时监控。这样,可在屏幕上直接看到系统所控制设备的实时状态。家居智能系统人机交互终端作为智能化系统与用户的信息交互平台,由图形用户界面、LCD液晶显示屏、信息输入按键、状态指示灯、紧急报警按键等部分构成,采用菜单查询、信息交流的简捷方式,实现了智能系统与用户的交流,架起了业主与物业之间沟通的桥梁。
图形用户界面(GUI-Graphics User Interface)是当前用户界面的主流,广泛应用于各档台式微机和图形工作站。图形用户界面和人机交互过程极大地依赖视觉和手动控制的参与,因此具有强烈的直接操作特点。
图形用户界面(GUI)的广泛流行是当今计算机技术的重大成就之一,它极大地方便了非专业用户的使用,人们不再需要死记硬背大量的命令,而可以通过窗口、菜单方便地进行操作 。一个图形用户界面系统通常由三个基本层次组成。它们是显示模型,窗口模型和用户模型。图形用户界面的主要特征:一个屏幕上可以有多个窗口,图符系形象化的图形标志,易于人们隐喻和理解,便于用户直接对屏幕对象进行操作。 采用GUI后,用户可直接对屏幕上的对象进行操作,如拖动、删除、插入以至放大和旋转等。用户执行操作后,屏幕能立即给出反馈信息或结果,给用户带来了方便。
随着虚拟现实、科学计算可视化及多媒体技术的飞速发展,新的人机交互技术不断出现,更加自然的交互方式将逐渐为人们所重视。新一代界面的主要特征是以用户为中心, 以用户对界面的需求变化为出发点,使用户界面的外在形式和内部机制能符合不同用户的需要;多通道,充分利用一个以上的感觉和运动通道的互补特性来捕捉用户的意向,从而增进人机交互中的自然性; 智能化, 精确交互技术是指能用一种技术来完全说明用户交互目的的交互方式,键盘和鼠标器均需用户精确输入;高带宽, 新一代的用户界面应该支持高的输入带宽,快速大批量地输入信息;不限制地点 ,采用语音输入输出或其他计算机视觉(摄像输入)技术,则可不受地点的限制;图示编程,比较简单和直观,便于交互修改、控制时间关系。
与通用的图形用户界面系统相比,嵌入式系统下的图形用户界面具有轻型、占用资源少,高性能,高可靠性,可配置等特点。常见的的用户界面都非常简单,几乎看不到 PC 机上华丽美观的 GUI 界面。最近出现的 Palm 等手持式电脑或者在 Windows CE 等面向嵌入式系统的操作系统上,我们已经看到了完整的图形用户界面支持。随着手持式设备的硬件条件的提高,嵌入式系统对轻量级 GUI 的需求会越来越迫切。
嵌入式图形用户界面为嵌入式系统提供了一种应用于特殊场合的人机交互接口。用户通过GUI可以直观地观察系统的状态、参数、数据和数据的图形表示,也可以通过GUI方便地完成设备的操作和控制。GUI可以一改过去嵌入式系统的黑匣子样式,可以极大地提供系统的可用性,因此,尽管GUI功能添加需要较高的成本,但也逐渐在越来越多的嵌入式系统中采用。
2硬件体系结构
2.1开发板硬件资源
本课题是基于博创嵌入式开发平台UP-NET ARM3000上实现的,UP-NETARM3000是比较成熟的ARM7嵌入式教学科研实验系统。它采用模块化的设计理念, 更加强调应用,移植了目前最为流行的实时、开放源码的双操作系统μC/OS-II和UCLinux,实现了对不同专业教学要求的全覆盖,其主要硬件资源包括:
1)CPU:S3C44B0X,ARM7TDMI,工作在 60MHz
2)BIOS:1M,NOR FLASH
3)内存:8M,SDRAM
4)海量存储器:16M,NANDFlash
5)键盘:17键数字小键盘
6)显示器:320 240 的 16 级灰度LCD(可选 256 彩色 LCD),四线电阻式触摸屏
7)USB 接口:1.1 标准
8)串行口:两个,最高波特率 115200kb
9)网络接口:10M 以太网
10)CAN接口:125Kb,250Kb,500Kb,1Mb
11)调试接口:JTAG,14 针,20 针
12)电机:直流电机(有刷),步进电机(带 1/64 减速器)
13)A/D:8路 10 位,满量程 2.5V,已用前 4 路
14)D/A:10 位,满量程 4.096V
15)LED:8个,共阴极
16)音频输出:44.1KHz
2.2CPU-S3C44B0X
S3C44B0X微处理器是三星公司专为手持设备和一般应用提供的高性价比和高性能的微控制器解决方案。它使用ARM7TDMI核,工作在66MHz,集成了LCD控制器等外围器件。它的LCD控制器具有通用性,能与大多数LCD显示模块接口。接口设计、驱动程序开发都很简单,广泛应用于智能仪表、PDA等的显示部分。
S3c44B0X开发板(标准版)是ARM开发套件。该套件功能强大,可接320x240,640x480  LCD。10M网口,尺寸小巧,本文转载自http://www.biyezuopin.vip/onews.asp?id=12806布线美观,价格低廉,是目前国内最精致的ARM开发板。44B0X 配置JTAG调试头,是ARM开发者的必备的利器。
电路图如下图所示:
21 S3c44B0X的电路图
void stateTimerTask (WINDOW_DATA * pData)
{
UGL_RECT windowRect;
char tmp_string[100];
float value;
while (!pData->timerExit)
{
winDrawStart (pData->windowId, gc, UGL_FALSE);
winRectGet (pData->windowId, &windowRect);
uglForegroundColorSet (gc, colorTable[GREEN].uglColor);
uglBackgroundColorSet (gc, colorTable[BLACK].uglColor);
uglTextDraw (gc, windowRect.left + 20, windowRect.top + 20, -1, "检查空气质量");
uglTextDraw (gc, windowRect.left + 20, windowRect.top + 40, -1,"检查光线");
uglTextDraw (gc, windowRect.left + 20, windowRect.top + 60, -1, "测量温度");
uglTextDraw (gc, windowRect.left + 20, windowRect.top + 80, -1,"检查水流开关");
uglTextDraw (gc, windowRect.left + 20, windowRect.top + 100, -1,"检查门窗");
uglForegroundColorSet (gc, colorTable[YELLOW].uglColor);
uglTextDraw (gc, windowRect.left + 100, windowRect.top + 20, -1, "空气质量良好");
uglTextDraw (gc, windowRect.left + 100, windowRect.top + 40, -1,"光线偏低");
uglTextDraw (gc, windowRect.left + 100, windowRect.top + 60, -1, "室温良好");
uglTextDraw (gc, windowRect.left + 100, windowRect.top + 80, -1, "水流正常");
uglTextDraw (gc, windowRect.left + 100, windowRect.top + 100, -1, "门窗都已关闭");
uglRectangle (gc, 200, 0, 320,240);
uglTextDraw (gc, 205, 5, -1, "报警原因");
uglForegroundColorSet (gc, colorTable[YELLOW].uglColor);
uglTextDraw (gc, 210, 20, -1,"否 电压故障");
uglForegroundColorSet (gc, colorTable[YELLOW].uglColor);
uglTextDraw (gc, 210, 40, -1,"否 空气质量异常");
uglForegroundColorSet (gc, colorTable[YELLOW].uglColor);
uglTextDraw (gc, 210, 60, -1,"否 温度异常");
uglForegroundColorSet (gc, colorTable[RED].uglColor);
uglTextDraw (gc, 210, 80, -1,"是 光线偏低");
uglForegroundColorSet (gc, colorTable[YELLOW].uglColor);
uglTextDraw (gc, 210, 100, -1, "否 门窗异常");
uglForegroundColorSet (gc, colorTable[YELLOW].uglColor);
uglTextDraw (gc, 210, 120, -1, "否 水开关异常");
uglForegroundColorSet (gc, colorTable[YELLOW].uglColor);
uglTextDraw (gc, 210, 140, -1,"否 负荷超载");
uglForegroundColorSet (gc, colorTable[YELLOW].uglColor);
uglTextDraw (gc, 210, 160, -1, "否 输出电压偏低");
winDrawEnd (pData->windowId, gc, UGL_FALSE);
uglOSTaskDelay (100);
}
pData->timerTaskId = UGL_NULL_ID;
}
void winState(int x, int y)
{
UGL_APP_ID appId;
UGL_WINDOW_ID selfWindowId;
UGL_BOOL winExit;
UGL_EVENT event;
WINDOW_DATA winData;
appId = winAppCreate (eventRouterId, 100);
selfWindowId = winCreate (appId, 0, 0, 320, 240);
winAttach (UGL_NULL_ID, selfWindowId, UGL_NULL_ID);
winData.windowId = selfWindowId;
winData.timerExit=FALSE;
winData.timerTaskId = uglOSTaskCreate ("stateTimer",
(UGL_FPTR)stateTimerTask, 250,
(UGL_UINT32)&winData);
winExit = UGL_FALSE;
while (winExit != UGL_TRUE)
{
if (winEventGet (appId, &event, 200) != UGL_STATUS_OK)
continue;
switch (event.header.type)
{
case WIN_EVENT_TYPE_DRAW:
{
UGL_WINDOW_ID windowId = (UGL_WINDOW_ID)event.header.objectId;
UGL_RECT windowRect;
winDrawStart (windowId, gc, UGL_TRUE);
winRectGet (windowId, &windowRect);
UGL_RECT_MOVE_TO (windowRect, 0, 0);
uglForegroundColorSet (gc, colorTable[BLACK].uglColor);
uglBackgroundColorSet (gc, colorTable[BLUE].uglColor);
uglRectangle (gc, windowRect.left, windowRect.top,
windowRect.right, windowRect.bottom);
winDrawEnd (windowId, gc, UGL_TRUE);
taskDelay (1);
}
break;
case UGL_EVENT_TYPE_POINTER:
{
UGL_INPUT_EVENT * pInputEvent = (UGL_INPUT_EVENT *)&event;
UGL_WINDOW_ID windowId = (UGL_WINDOW_ID)event.header.objectId;
if (UGL_BUTTON1_DOWN (&event) || UGL_BUTTON2_DOWN (&event)){
winData.timerExit=UGL_TRUE;
winExit=UGL_TRUE;
}
}
default:
}
}
while (winData.timerTaskId != UGL_NULL_ID)
uglOSTaskDelay (10);
winDetach (UGL_NULL_ID, selfWindowId);
winDestroy (selfWindowId);
winAppDestroy (appId);
}