更全的杂志信息网

emWin GUI的RFID手持终端界面设计*

更新时间:2016-07-05

引 言

伴随着嵌入式技术的成熟,人性化图形用户界面在嵌入式系统中的应用愈发广泛[1]。图形用户界面(Graphical User Interface,简称GUI),是指采用图形方式显示的计算机操作用户界面。与命令行界面相比,图形界面对于大部分用户来说更易于接受和操作。

RFID手持终端致力于解决当前物流行业取货、运输、配送等场合出现的问题。同时为了降低设备成本且方便一线员工使用,本文采用Cortex-M4内核的STM32F407ZGT6作为处理器,辅以FreeRTOS操作系统和emWin GUI设计出简单易操作的GUI界面用于人机交互,能够很好地满足实际需要。

1 RFID手持终端简介

随着物联网普及和物流行业的快速发展,RFID标签代替条码标签的趋势愈发明显,为了方便物流运输环节运输员对RFID标签的操作,包括取货环节输入运单号和送货环节读取商品信息,并与物流数据中心保持信息交互,本文设计的RFID终端包括硬件和软件部分。

1.1 硬件组成

考虑到RFID手持终端需要对标签进行读写,与物流数据中心保持信息交互,并有很好的可操作性,故设计一款采用ARM 32位Cortex-M4内核的STM32F407ZGT6作为主控芯片,SIM800C作为数据传输模块,MD3650A-HA 作为射频读写模块,且使用ATK-7’TFT LCD电容触摸屏作为人机交互的RFID手持终端。另外,为了显示快递实时定位信息,给RFID手持终端增加GPS定位功能,以满足快递取货送货最后一公里的真实需求。

写运单号面设计图如图1所示。

图1 写运单号面设计图

1.2 软件组成

综合对RFID终端的使用场景、功能、成本、开发难度等方面考虑,采用轻量级FreeRTOS作为终端操作系统,其具有最小的ROM、RAM和处理开销且能提供任务管理、时间管理等一系列常用功能,其完全免费,源码公开,同时具有可移植、可裁减、调度策略灵活的特点。二次开发简单,可以方便地移植到各种单片机上运行[2-3],能够很好满足终端的使用需求。

2 嵌入式GUI

目前在嵌入式平台上可用的GUI产品比较丰富,但大体上可分为如下几类。

① 低端嵌入式GUI:包括emWin(μCGUI)、RT-Thread/GUI,此类GUI适用于单片机、ARM7、ARM Cortex-M等平台,多与简单的RTOS系统(比如FreeRTOS、μC/OS、RT-Thread)配合使用,开发语言为C语言。

② 中端嵌入式GUI:包括miniGUI、OpenGUI、Microwindows等等,主要适用于ATM7、ARM9、ARM11、ARM Cortex-R等平台,多与嵌入式Linux、μCLinux操作系统配合使用,开发语言为C语言。

③ 高端嵌入式GUI:包括Qt/Embedded、Android、MFC等,主要适用于ARM9、ARM11、ARM Cortex-A等平台,多与嵌入式Linux、Win CE/Win Phone操作系统配合使用,开发语言为C++和JAVA语言。

介于本文设计的物联网终端主核芯片为ARM Cortex-M4架构的STM32F407,且采用的操作系统为FreeRTOS,结合手持终端要求的功耗低、成本低、性价比高等要求,选定SEGGER公司授权给ST(意法半导体)的STemwin,使用ST芯片的用户均可以免费试用。emWin软件架构和功能成熟,通过调用emWin提供的函数接口,可为图形LCD操作任何应用程序提供方便有效且与处理器和LCD控制器无关的图形用户界面(GUI)。而且emWin对ROM和RAM的消耗并不高,这使得其在嵌入式人机交互场合广受欢迎。

2.1 emWin简介

emWin是德国SEGGER公司的一个嵌入式GUI图形库,GUI图形库的概念就好像它是一个平台,我们只需要在这个平台上通过其提供的方法写自己的用户界面应用程序,非常简单、便捷。

生活是平凡的,但是能够坚守平凡的人,总能找到不凡的价值。高塔上发短视频的电网工人,为何能收获无数粉丝的感佩?也许不仅是因为艰苦,更因为传递光明。《人民日报》“中国道路中国梦”栏目也曾刊登过一位电网工人的文章。作者是孩子眼中的“蜘蛛侠”,一边爬高一边拉线。200多米的塔相当于80多层楼,爬上去要迈过1268级台阶。工作甘苦自知,但在塔顶俯视长江,会感觉它变窄了,而自己和塔上的队友却变得高大了。

2.2 emWin组成

在emWin界面应用程序中,每个页面都是由三部分组成:

① 控件结构体数组:控件结构体数组包括此页面用到的所有控件。

② 回调函数:每个页面都对应这着一个回调函数,对界面进行的任何操作都会跳转到回调函数里面对对应的消息函数进行处理。

③ 页面创建函数:所有的页面和控件都对应一个句柄,通过句柄和ID可以找到并管理任意的页面和控件。

高中数学教学过程中对微课的应用方便解决教学中的难点,高中阶段的数学知识相对比较抽象,重点以及难点也比较多,是学生学习数学知识的阻碍.传统的教学模式很难高效地解决这些问题,而通过新的教学模式,将微课运用到数学课堂中,这就能针对性地突破学习难点,让学生通过观看视频的方式,动态化地了解重点以及难点的解决方式,将复杂的问题简单化呈现,从而带动学生主动地探究数学知识,对提高学生自主学习能力也有着促进作用.

另外,控件句柄、控件ID 、消息也是非常重要的三个元素。其具体实现如下:

static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] =//控件结构体数组{

控件(ID_0)

控件(ID_1)

……

控件(ID_x)

};

static void _cbDialog(WM_MESSAGE* pMsg){ //回调函数

液晶驱动最核心的函数是画点函数,可以认为几乎所有的emWin显示功能都是通过最终调用画点函数来实现的[4],本设计画点函数设计如下:

//窗口重绘消息,要在Framewin或Window窗口之中显示文字

//或绘制直线、矩形、圆等在这里实现

……

case WM_INIT_DIALOG:

//初始化消息,创建窗口/控件时对其初始化参数进行设置,即

因为E‖x(t)‖=x(0)+E‖v(s)‖ds≤x(0)+D0t,存在T1>0, m1>0,使得当t>T1时,有

3.1.3 医学图书馆的信息基础设施要完善。信息基础设施是决定一个学校图书馆的基础能力和存储能力。目前,学校的存储能力还停留在结构化数据中,远远不能满足现在网络信息产生的数据,大数据时代可以智能分析计算能力,能高效的获取、存储和分析TB、PB级别的数据。这对医学图书馆的软硬件设施提出了巨大的挑战。

//显示的是未操作时的界面

……

case WM_NOTIFY_PARENT:

//操作触发消息处理(操作屏幕程序会跑到这里),一般功能函

女助手说:“是的,可是医院也是可以调节的,专家坐诊时间并不是一成不变的。这个时间我当时也问了毛老师的,是他自己亲自改的。”

emWin设计用于提供高效且独立于处理器和显示控制器的图形用户界面,用于任何使用图形显示进行操作的应用。它与单任务和多任务环境、专用操作系统或任何具有商业RTOS系统均兼容,同时由于其源代码开放,使得开发难度大大降低。

//数放在此消息下,比如点击按键、点击编辑框(任何的操作)所

//实现的功能

……

}

“操他大爷的,医生的话你也信!”房东说。“女人检查身体,医生都敢说出前列腺来。”说完房东朗声大笑,大肚腩像小山一样晃悠着。

hWin= GUI_CreateDialogBox(控件结构体数组, 回调函数, 父窗口句柄); //页面创建函数,返回该页面句柄,即hWin

3 emWin移植

移植包括对emWin进行参数配置、LCD驱动程序、触摸屏驱动程序编写以及emWin与FreeRTOS操作系统接口修改等。

3.1 emWin配置文件参数

主要是针对实际情况进行相应的参数调整,本文采用LCD规格为800×480,控制器为GT811。

3.1.1 修改GUICong.c

在GUICong.c为emWin分配内存,这里使用外部RAM。代码如下:

OA学术资源导航是指图书馆将网络上的OA学术资源通过网站链接的方式呈现在本馆网页上。对于图书馆来说,在本馆主页上建立OA学术资源网站链接,使用户通过点击链接直接访问OA学术资源网站获取信息,是推动OA学术资源建设,提高OA学术资源的利用率的直接途径。在军队网络保密,军网与互联网物理隔离的环境下,若想实现通过网站链接直接访问互联网OA学术资源网站,需在互联网上的军队院校图书馆首页建立OA学术资源网站链接,用户在图书馆内的互联网阅览室进行浏览查阅。

GUI_SetDefaultFont(GUI_FONT_6X8); //设置字体

#define GUI_BLOCKSIZE 0X80 //块大小

void GUI_X_Config(void){

U32*aMemory=mymalloc(SRAMEX,GUI_NUMBYTES); //从外部RAM中分配内存

GUI_ALLOC_AssignMemory((void*)aMemory, GUI_NUMBYTES); //为存储管理系统分配存储块

1)滨海新区地域文化形式多样,内涵丰富。天津滨海新区以码头文化为基础滋生孕育出丰富多样的民俗文化,如相声、戏曲、大港布贴画、北方剪纸、汉沽刻字版画等民俗民艺,这些民俗文化来源于生活,高于生活,受到人们的喜爱。以码头文化为主的民俗文化是天津滨海新区的文化源头,极具包容性,促进了多样化传统艺术的相互交融,不断发展,推陈出新,形成了具有津门特色的文化形式。

GUI_ALLOC_SetAvBlockSize(GUI_BLOCKSIZE); //设置块大小

经调查,精准农业应用系统在全县的农机专业合作应用达到99%以上,发展空间十分广阔,但由于受使用者文化水平、经济承受能力和传统农业种植的影响,精准农业系统发展缓慢。

#define GUI_NUMBYTES (500×1024)

}

//设置EMWIN内存大小

3.1.3 配置LCDConf.h

在GUICong.h中进行功能配置修改,设置如下:

#define GUI_NUM_LAYERS 10 //显示的最大层数

在观察组的60例中,有6例遭投诉,投诉率为10.0%,在对照组的60例中,有19例遭投诉,投诉率为31.7%,组间比较,差异有统计学意义(x2=8.5389,P<0.01)。

#define GUI_OS (1) //使用操作系统

#define GUI_MAXTASK(5)

//最大可调用Emwin任务数

#define GUI_SUPPORT_TOUCH (1) //支持触摸

#define GUI_DEFAULT_FONT &GUI_Font6x8 //默认字体

#define GUI_SUPPORT_MOUSE (1) //支持鼠标

总之,基于共享型生活服务平台的社区价值共创,除产生了直接价值外,社区主体要素间的相互联系和信任度增加,彼此间建立起更强烈的情感联系,同时社会资本增加,也对顾客忠诚度产生了积极正面影响,这些因素均促使社区整体和谐度提升。

SWI即为磁敏感加权成像,主要是应用磁场之中组织内部或局部间此命案差异而出现的磁共振成像对比的一种T2脉冲序列技术,目前已经被广泛的而应以在出血性病变之中[1]。本文选取2015年10月—2018年10月我院进行治疗的肝胆病变中盲选46例作为纳入本次研究之中,分析1.5T磁共振SWI序列应用在肝胆病变患者诊断中所取得的临床效果,对1.5T磁共振SWI序列应用在临床中的价值展开探究,研究内容报告如下。

(1) TBM卡机的根本原因是高海拔、大断层、大埋深等复杂地质条件引起高地应力,致使掌子面发生大规模塌方,TBM主机部位的围岩快速发生收敛变形,导致TBM主机整体被周边围岩完全抱死。

#define GUI_WINSUPPORT (1) //窗口管理

#define GUI_SUPPORT_MEMDEV (1) //存储设备

#define GUI_SUPPORT_DEVICES (1) //使用设备指针

3.1.2 修改GUICong.h

根据触摸屏的具体规格来修改LCDConf.h 文件里面的参数,设置如下:

#define XSIZE_PHYS 800 //LCD 每一行的像素数

#define YSIZE_PHYS 480 ///LCD 的行数

#define COLOR_CONVERSION GUICC_M565

//选择RGB565色彩模式

#define TOUCH_AD_TOP160

//按下触摸屏的顶部,写下Y轴模拟输入值

#define TOUCH_AD_BOTTOM3990

//按下触摸屏的底部,写下Y轴模拟输入值

#define TOUCH_AD_LEFT160

//按下触摸屏的左侧,写下X轴模拟输入值

#define TOUCH_AD_RIGHT3990

//按下触摸屏的右侧,写下X轴模拟输入值

#define CT_EXCHG_XY 1 //调转 XY 坐标

#define CT_MAX_TOUCH 5 //电容触摸屏最大支持的点数

3.2 LCD画点程序

case WM_PAINT:

//画点,x,y:坐标,POINT_COLOR:此点颜色值

void LCD_DrawPoint(u16 x,u16 y){

LCD_SetCursor(x,y); //设置光标位置

LCD_WriteRAM_Prepare(); //开始写入GRAM

TFTLCD->LCD_RAM=POINT_COLOR;

}

3.3 LCD触摸屏驱动程序

STM32F407通过FSMC总线与触摸屏模块相连,首先调用GT811_Init()函数用于初始化电容触摸屏驱动芯片GT811,并在其中开启外部中断1,使用GT811_Send_Cfg发送GT811的配置参数。初始化完成后,每当GT811有数据可供读取的时候,CPU就可以在CT_INT信号上接收到一个脉冲信号(100us左右的低电平脉冲),CPU只需要在接收到CT_INT中断后,调用GT811_Scan()函数依次读取GT811的输出信息寄存器,将读取到的数据组织起来,就可以获得最多5个点的触摸数据。

3.4 操作系统相关接口部分的修改

FreeRTOS移植成功后,便可以将emWin与CPU的相关部分交给FreeRTOS处理,即需要提供一些内核接口函数来实现emWin在FreeRTOS上的运行。任务调度相关接口函数实现如下:

//GUI延时函数

void GUI_X_Delay(int period) {

vTaskDelay(period);}

void GUI_X_InitOS(void){

osMutex=xSemaphoreCreateMutex();//创建互斥信号量

vSemaphoreCreateBinary(osSemaphore);//创建二值信号量

}

//等待信号量

void GUI_X_Lock(void){

xSemaphoreTake(osMutex,portMAX_DELAY);

//请求信号量

}

//发送信号量

void GUI_X_Unlock(void){

xSemaphoreGive(osMutex);//释放信号量

}

//返回任务ID

U32 GUI_X_GetTaskId(void){

return((uint32_t)xTaskGetCurrentTaskHandle());

//获取任务ID

}

至此,emWin GUI的移植基本上完成,需要编写测试用例,如果显示效果不理想,再对移植的GUI进行底层配置优化和改进。

4 用户界面设计与功能实现

4.1 设计流程

本项目利用emWin的配套工具GUIBuilder,允许不使用C语言的情况下,编程图形创建对话框。可以对窗口小部件进行创建、拖曳、删除和调整大小等操作,以实现组态、拖放式人机用户界面设计[5]。GUIBuilder操作界面非常简单、一目了然,生成的界面文件是标准C文件,将生成的C文件加到emWin工程中,并在emWin这个图形库平台上运行,即可显示所设计的界面。

初步界面设计完成后,用CodeBlocks进行模拟显示,CodeBlocks是emWin脱机模拟仿真开发环境软件,将emWin GUIBuilder保存的.c文件复制到Codeblocks示例文件的Application文件中,在LCDConf.c里面设置屏幕尺寸,GUIDEMO_Start.c里面创建主窗体,加入中文显示库和代码并在对应按钮消息下添加界面转换函数,便可模拟出GUIBuilder所设计的界面。

通过C语言和API函数对照emWin使用手册可对模拟界面进行完善,以设计出更友善的人机交互界面。

最后将CodeBlocks中的C文件加入μVision工程中,并添加相应的功能实现代码,烧录进单片机之后便可进行实际测试。

物联网终端拟设计主界面和4个子界面,子界面分别为读标签信息、写入运单号、设置、GPRS数据传送。下面就主界面和RFID标签读写等三个界面进行具体分析。

4.2 RFID终端界面设计

GUIBuilder设计界面如图2所示。模拟图如图3所示。

图2 主界面设计图

图3 主界面模拟图

控件结构体数组为:

static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {

{FRAMEWIN_CreateIndirect, "TFT LCD", ID_FRAMEWIN_0, 0, 0, 800, 480, 0, 0x64, 0},

{ BUTTON_CreateIndirect, "read data", ID_BUTTON_0, 189, 126, 107, 33, 0, 0x0, 0 },

{ BUTTON_CreateIndirect, "write RFID", ID_BUTTON_1, 187, 240, 110, 35, 0, 0x0, 0 },

{ BUTTON_CreateIndirect, "send data", ID_BUTTON_2, 385, 241, 110, 37, 0, 0x0, 0 },

{ IMAGE_CreateIndirect, "Image", ID_IMAGE_0, 619, 318, 97, 99, 0, 0, 0 },

{ BUTTON_CreateIndirect, "Button", ID_BUTTON_3, 385, 123, 109, 33, 0, 0x0, 0 },

};

主要成员方法见表1。

表1 终端界面成员方法表

按钮名称方法名称作 用读标签信息CreateRead()转到读标签信息界面输入运单号Createwrite()转到写运单号界面数据传递CreateGPRS()转到GPRS数据传递界面设置Createset()转到系统设置界面

4.3 写运单号界面

GUIBuilder设计界面如图4所示。模拟图如图5所示。

图4 写运单号面设计图

图5 写运单号面模拟图

用12个按钮来分别模拟数字0~9、空格和删除键,其中数字和空格的按钮操作触发消息处理函数为:

void Button_trans(char k){

int i;

for(i=0;i<20;i++){

if(trans_number[i] == ''){

trans_number[i] = k;

break;

}

}

}

删除的按钮操作触发消息处理函数为:

void Button_delete(){

int i;

for(i=0;i<20;i++){

if(trans_number[i] == ''){

trans_number[i-1] = '';

break;

}

}

}

标签注册的按钮操作触发消息处理程序为:

case ID_BUTTON_1: //通过“标签注册”发送的通知

switch(NCode) {

case WM_NOTIFICATION_CLICKED:

//点击按钮

break;

case WM_NOTIFICATION_RELEASED:

//松开按钮

memcpy(Operating_state,Operation_failed,20);

//操作提示信息初始化

hItem = WM_GetDialogItem(pMsg->hWin, ID_EDIT_0);

//当前句柄指向标签订单号编辑框

EDIT_GetText(hItem, trans_number,trans_num_len);

//获取有效长度的编辑框数据

EDIT_SetText(hItem, trans_number);

//将有效长度的数据重新写入编辑框

WRITE_RFID_trans_number(trans_number);

//将订单号写入RFID标签的第一个扇区第1数据块

hItem = WM_GetDialogItem(pMsg->hWin, ID_TEXT_1);

//当前句柄指向操作提示消息框

TEXT_SetText(hItem, Operating_state);

//写入操作提示消息

break;

}

break;

由程序可知,点击标签注册按钮并松开后,系统首先初始化操作提示消息数组,然后将句柄指向标签订单号编辑框,再获取用户输入到编辑框的指定长度的订单号并重新输出到编辑框中,然后将订单号写入RFID标签,如标签写入成功,就在操作提示框显示操作成功提示符。

其中写订单号到RFID标签函数如下:

void WRITE_RFID_trans_number(uint8_tt trans_number[]){

unsigned char buffWrite[50] = {0x01, 0x17, 0xA4, 0x20, 0x01, 0x01, 0x00};

//写块数据指令

buffWrite[4] = 1; //指定数据块

for(i = 0; i < 16 && trans_number[i] !='/0'; i++){

buffWrite[i+6] = trans_number[i];

}

arr_end = buffWrite[1] - 1;

buffWrite[arr_end] = Checksum(buffWrite, buffWrite[1]); //计算校验和

cortexSendStringUart2(buffWrite,buffWrite[1]);

//将指令输出到RFID模块

buffRead = (uint8_tt *)malloc(32);

//申请接收数据空间并初始化

memset(buffRead, 0, 1);

data2_len = USART2_RX_STA & 0X3FFF;

//计算接收到的数据长度

memcpy(buffRead,USART2_RX_BUF,data2_len);

//接收RFID模块返回数据

USART2_RX_STA=0;

//判断是否接收成功,并将操作状态信息写入操作状态数组

...

free(buffRead); //释放申请的空间

4.4 读标签信息界面

GUIBuilder设计界面如图6所示。模拟图如图7所示。

图6 读标签信息界面设计图

图7 读标签信息界面模拟图

读数据按钮操作触发消息处理程序为:

case ID_BUTTON_0: //通过“读数据”按钮发送的通知

switch(NCode) {

case WM_NOTIFICATION_CLICKED: //点击按钮

break;

case WM_NOTIFICATION_RELEASED: //松开按钮

memcpy(Operating_state,

Operation_failed,20);

//操作提示信息初始化

READ_RFID_trans_number(); //读运单号函数

TEXT_SetText(hItem, data_usart1);

...

hItem = WM_GetDialogItem

(pMsg->hWin, ID_TEXT_4);

TEXT_SetText(hItem, Operating_state);

//写入操作提示信息

break;

}

break;

由程序可知,点击标签注册按钮并松开后,系统首先初始化操作提示消息数组,然后执行读运单号函数,将标签运单号读出并显示在屏幕上,然后依次读取标签中其他信息并对应显示,如标签写入成功,就在操作提示框显示操作成功提示符。

5 性能测试与实验分析

将程序烧录进RFID手持终端主核芯片后,对产品功能进行测试。首先,通过按钮操作,成功实现将订单号输入到RFID标签之中。其次,读取出来的运单号与之前写入标签的运单号一致,读出的其它信息则是由信息处理中心写入标签。订单号和定位信息上传功能:通过触控操作显示屏获取并显示GPS信息,并将GPS信息与写入标签的订单号信息打包成数据块通过GPRS发送给远程服务器。

结 语

本设计成功实现了emWin GUI在RFID手持终端上的移植,能够显示自定义的图片、字体、消息框等,移植的界面设计简单、操作方便灵活、能够实现预定功能,完美地解决了手持终端的使用需求问题。emWin移植简便,界面设计方便实用,适用于工业应用、医疗器械、电子产品等嵌入式电子产品的显示开发,必定会在嵌入式系统的人机界面系统中得到广泛的应用[6]

参考文献

[1] Wang T, Chen H P.Application of XML to Development of GUI in Embedded System[J].Journal of Wuhan Yejin University of Science & Technology, 2005(1).

[2] 刘滨, 王琦, 刘丽丽.嵌入式操作系统FreeRTOS的原理与实现[J].单片机与嵌入式系统应用, 2005(7):8-11.

[3] 朱迪.FreeRTOS实时操作系统任务调度优化的研究与实现[D].南京:南京邮电大学, 2015.

[4] 邵青.基于STM32F4x9的LCD显示设计方案[J].单片机与嵌入式系统应用,2014,14(6):82-83.

[5] 罗富文,吴辉,康伟,等.STM32平台的μC/GUI移植与图形界面设计[J].单片机与嵌入式系统应用,2012,12(8):19-22.

[6] 张峰, 张团善, 吕双庆,等.emWin在LPC1788上的移植与应用[J].电子设计工程, 2015(6):156-160.

张绍维,吴春然
《单片机与嵌入式系统应用》2018年第05期文献

服务严谨可靠 7×14小时在线支持 支持宝特邀商家 不满意退款

本站非杂志社官网,上千家国家级期刊、省级期刊、北大核心、南大核心、专业的职称论文发表网站。
职称论文发表、杂志论文发表、期刊征稿、期刊投稿,论文发表指导正规机构。是您首选最可靠,最快速的期刊论文发表网站。
免责声明:本网站部分资源、信息来源于网络,完全免费共享,仅供学习和研究使用,版权和著作权归原作者所有
如有不愿意被转载的情况,请通知我们删除已转载的信息 粤ICP备2023046998号