




下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、XMOVE3.0手持终端软件介绍:精简型嵌入式管理系统的菜单实现和任务切换一. 综述和废话本系统是我的XMOVE动作感应系统框架的嵌入式实现部分。一提到OS一般都会被人喷。OS是何等庞大的东西,区区小辈凭什么敢把自己的几百行代码称之为OS?叫做框架都不行! 有句话叫简单就是美。方便移植,使用简单的c语言框架,在单片机上再合适不过了。想象一下,一个嵌入式手持系统,在2KB内存的单片机上实现,硬件上有按键和图形界面,软件上有简单的任务调度和中断服务策略,一个还不错的菜单管理和用户GUI,输入输出接口和简单的无线通信协议,有小游戏,甚至还能听MP3,甚至还有中文输入法。给你这样的系统,你还
2、想要什么?所以我们称之为嵌入式管理系统,目前在430和STM32上成功移植和运行,可以支持不同颜色和分辨率的显示器,我会专门用一篇文章介绍其GUI实现。但目前我仅介绍其中的一部分:在嵌入式系统中如何实现简单的菜单和任务切换功能。 与XMOVE手持终端相关的介绍文章列表如下:硬件综述: 自制的彩屏手持动作感应终端软件综述:手持终端功能介绍软件介绍(一):精简型嵌入式系统的菜单实现和任务切换软件介绍(二):在2KB内存单片机上实现的彩屏GUI控件库软件介绍(三):在2KB内存单片机上实现的俄罗斯方块软件介绍(四):在2KB内存单片机上实现的超精简五子棋算法软件介绍(五):
3、在2KB内存的单片机上实现的T9中文输入法 下面是系统实际运行图这是该系统的12864单色屏版本12864单色屏版本主菜单四宫格320*240彩屏版本,菜单提供了三种风格和不同的配色,可以在系统设置中调节二. 系统总体框架 系统面向对实时性没有极端要求的应用,针对平台是内存10KB以内的嵌入式芯片,通常包含小型LCD屏幕和键盘的工控系统,通常系统会实现一些菜单和任务调度。为实现这个目标,搭建系统框架是非常必要的。必须满足以下几类要求:(1)可移植性,主控芯片和外围模块可变,满足硬件无关性。(2)采用占先式处理,形成任务队列。(3)低内存占用,将大型数据尽可能保存在FLASH
4、中。我们如何实现菜单呢?初步思路是switch-case块,系统通过键盘选择进入不同的子菜单,但子菜单终归要跳到主菜单的,用户的操作可能非常繁复,最后用swich-case这样的选择性结构根本没法描述复杂的菜单管理 。必须用改进的数据结构来描述,我们想到了图。但这样的图结构怎样描述呢?系统状态分为两类,菜单状态和任务状态。任何菜单页都可能有父菜单或子菜单,任务也可以看成只有父菜单而没有子菜单的特殊“菜单页”。同时每个任务都应该给出它的父菜单和子菜单值。这样就给出了任务状态转移图。当需要返回时,返回父菜单。若该菜单含有子菜单,则显示当前子菜单。1. 数据定义 我们对每个菜单项定义如下
5、的数据结构,与操作系统原理中的任务控制块(PCB)很相似。 struct TaskPCB /菜单结构 unsigned char *Name; /任务名称 u8 (* function)(); /指向的函数指针 unsigned char *Detail; /对该任务的描述 u8 PicIndex; /该任务的图片在图片数组中的ID u8 SubTaskList10; /第0项是父菜单,从第1项开始,分别对应子菜单标号 ; 我们将保存TaskPCB的结构体数组,由于它是不会改变的,因此加上const标示符,编译器会将其存储在FLASH中。每个任
6、务定义在数组中的偏移量就是该任务的唯一ID, 注释给出了结构体中成员的具体作用。此处我们重点解释下函数指针,数指针是指向函数的指针变量。 因而“函数指针”本身首先应是指针变量,只不过该指针变量指向函数。这正如用指针变量可指向整型变量、字符型、数组一样,这里是指向函数。 将一个包含相同返回值和形参表的函数赋值给函数指针,执行该指针即等效于执行该函数。 运行时可以动态改变该指针指向的内容,从而修改程序运行方向,这就是c语言的“动态性”。C#里的委托在本质上也是函数指针,只不过它是面向对象和安全的,整个面向对象大厦就建立在委托之上,可见“函数指针”所表现的深刻内涵。我们定义如下的TaskPCB数组:
7、const struct TaskPCB myTaskPCBSIZE_OF_Task= /菜单定义 "系统主菜单",MenuGUI,"全局功能显示",5,0,6,14,20,8,33,9,10, /0 "系统时间",time_show,"查看当前系统的时间",8,8,0, /1 "加速度监测",AccShow,"三轴加速度检测",24,8,0, /2 "五子棋",Five,"人机和无线对战",23,9,0, /3 "俄罗斯方块
8、",TerisBrick,"经典游戏,支持横竖屏",8,9,0, /4 "气压和温度",PressureTest,"显示温度和气压状态",24,8,0, /5 "动作感应键盘",GyroKeyboard,"感受全新的字符动作输入",17,14,0, /6 "通信管理",WirelessControl,"管理通信方式和协议",11,10,0, /7 "传感器监测",MenuGUI,"检测当前环境状态",20,
9、0,6,1,2,5,19,12,16, /8 "娱乐功能",MenuGUI,"您可使用该系统自带游戏",22,0,4,3,4,15,28, /9 "系统管理",MenuGUI,"您可对该系统设置和管理",11,0,4,7,11,13,17, /10 "运行配置",OSConfigSet,"对功耗和功能的设置",19,10,0, /11/为了方便,仅显示了一部分 用一张结构图解释会更清楚:2. 实现菜单显示 有了以上的数据结构定义以后,显示
10、就变得很简单了。 对于所有的菜单,他们的函数指针都应该指向一个函数:菜单显示函数。 请注意,由于平台不同,编码者的意愿也有所区别,该函数的实现可以非常灵活,多种多样。 若该页是菜单,那么它的函数指针地址将指向菜单显示,通过当前的index,它会绘制出该菜单的子菜单,并完成菜单的选取和管理操作。并等待用户输入:方向键光标发生移动,跳出则系统返回父菜单,点选确定则进入子菜单项。我仅仅提供不完整的函数实现示意: (PS:这些代码是我大四时候写的,现在看都不一定能看得懂了.大家凑乎看看,其实有第一部分的数据结构,实现菜单就不成问题了)/*函数:u8 MenuGUI() 功能:显示不同风格的菜单界面参数
11、:(全局变量)MenuType指出当前显示的界面风格,参见界面编辑的相关说明返回值:固定为1*/u8 MenuGUI() /图形化界面窗口函数 switch(MenuType) case 0: MainMenuListGUI(1,3,200,64); break; case 1: MainMenuListGUI(1,8,0,25); break; case 2: MainMenuListGUI(3,2,100,90); break; return 1; 函数:u8 MainMenuListGUI()功能:主菜单界面的函数,负责绘图和和获得用户选择参数:LRMaxMount菜单左右显示
12、的最大数量,UDMaxMount:上下显示的最大数量, OneLRLength:任一项在界面中的最大像素宽度,OneUDLength:任一项的最大像素长度返回值:固定返回1*/u8 MainMenuListGUI(u8 LRMaxMount,u8 UDMaxMount,u8 OneLRLength,u8 OneUDLength) if (myTaskPCBOS_index_data.function!=MenuGUI) /如果要执行的不是界面绘制,则返回 return 0; u8 MaxMount=myTaskPCBOS_index_data.SubTaskList1; u8 func_sta
13、te=0,menu_flag=1,LastFlag,TotalFreshEN=1,flag=1,FreshEN=1; if(func_state=0) TaskBoxGUI_P(X_Witch_cn,Y_Witch_cn,Dis_X_MAX-X_Witch_cn,Dis_Y_MAX-Y_Witch_cn-3,(u8 *)myTaskPCBOS_index_data.Name,0); func_state=1; while(func_state=1) MenuDataRefreshGUI( menu_flag, MaxMount, flag, LastFlag, LRMaxMount,UDMax
14、Mount, OneLRLength, OneUDLength,FreshEN,TotalFreshEN); LastFlag=flag; switch(UpdownListInputControl(&menu_flag,&flag,MaxMount,LRMaxMount,UDMaxMount,1,&FreshEN,&TotalFreshEN) /系统会在此处接收用户输入 case 0: OSTaskClose(); /返回到父菜单 func_state=2; return 1; case 1: func_state=2; break; OS_index_dat
15、a= myTaskPCBOS_index_data.SubTaskListmenu_flag+flag; /核心:通过菜单项改变OS_index_data,从而实现任务切换,见第三节 return 1; 还有接收用户输入的函数 接收用户输入的函数 /*u8 UpdownListInputControl(u8 *Menuflag,u8 *ThisPageflag,u8 *TotolFlag,u8 *ThisPageMax)功能:菜单输入控制方法,用于上下类型的菜单参数:Menuflag,全页面标志计数器,ThisPageflag当前页面标志计数器,
16、TotolFlag总页面条数,ThisPageMax当前页面最大数量,PromptEN:是否提示到目录头或者结尾返回值:0:退出 1, 确认,2:仅仅选择了移动位置*/u8 UpdownListInputControl(u8 *Menuflag,u8 *ThisPageflag,u8 TotolFlag,u8 ThisPageLRMax, u8 ThisPageUDMax,u8 PromptEN,u8 *FreshEN,u8* TotalFreshEN) u8 LastMenuFlag=*Menuflag; u8 PromptFlag=0; u8 GyroKey=KEYNULL; *Fresh
17、EN=0; u8 myKey=KEYNULL; if(GyroControlEN=1) PromptEN=0; /当开启陀螺检测时,关闭提示 if(GyroControlEN=1&&back_light>1&&GyroMenuEN) delay_ms(300-20*TotolFlag); L3G4200DReadData(); L3G4200DShowData(); delay_ms(300-20*TotolFlag); else InputControl(); if(GyroMenuEN!=0) GyroKey=GyroKeyBoardInputMeth
18、od(0,1,300-30*ThisPageLRMax,300-20*ThisPageUDMax); if(GyroKey!=KEYNULL) myKey=GyroKey; else myKey=key_data; GyroKey=KEYNULL; switch(myKey) case KEYENTER_UP : return 1; /break; case KEYUP_UP : if(*ThisPageflag>ThisPageLRMax) (*ThisPageflag)-=ThisPageLRMax; else if(*Menuflag>ThisPageLRMax) (*Men
19、uflag)-=ThisPageLRMax; else if(*ThisPageflag=1&&PromptEN) PromptFlag=1; MessageGui("提示信息","已到目录开头",2); /else /*ThisPageflag=1; break; case KEYDOWN_UP : if(*ThisPageflag<=ThisPageLRMax*(ThisPageUDMax-1)&&*ThisPageflag+ThisPageLRMax<=TotolFlag) (*ThisPageflag)
20、+=ThisPageLRMax; else if(*Menuflag+*ThisPageflag-1<=TotolFlag-ThisPageLRMax) (*Menuflag)+=ThisPageLRMax; else if(TotolFlag=*ThisPageflag&&PromptEN) PromptFlag=1; MessageGui("提示信息","已到目录结尾",2); /else /*ThisPageflag= TotolFlag-*Menuflag+1; break; case KEYLEFT_UP : if(*Th
21、isPageflag>1) (*ThisPageflag)-; else if(*Menuflag>1) (*Menuflag)-; else if(PromptEN) MessageGui("提示信息","已到目录开头",2); PromptFlag=1; break; case KEYRIGHT_UP : if(*ThisPageflag<TotolFlag) (*ThisPageflag)+; else if(*Menuflag+*ThisPageflag-1<TotolFlag) (*Menuflag)+; else if(PromptEN) MessageGui("提示信息","已到目录结尾",2); PromptFlag=1; break; case KEYCANCEL_UP : return 0; if(key_data!=KEYNULL) *FreshEN=1; if(LastMenuFlag=*Menuflag&&PromptFlag=0) *TotalFreshEN=0; else *TotalFreshEN=1; return 2; 示意图如下:3. 实现任务调度我们介绍以下系统核心全局变量:OS_i
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 农发行长治市潞州区2025秋招小语种岗笔试题及答案
- 农发行丽水市缙云县2025秋招数据分析师笔试题及答案
- 农发行大同市天镇县2025秋招小语种岗笔试题及答案
- 国家能源蚌埠市淮上区2025秋招半结构化面试模拟30问及答案
- 成都青白江区中储粮2025秋招笔试题库含答案
- 保山隆阳区中储粮2025秋招笔试性格测评题专练及答案
- 成都彭州中储粮2025秋招网申填写模板含开放题范文
- 区域买卖合同(集合15篇)
- 关于弟子规的演讲稿15篇
- 刘秀祥先进事迹心得体会
- 急性心力衰竭急救
- 2024年中国充电基础设施服务质量发展报告
- 2024小学科学教师职称考试模拟试卷及参考答案
- 农村房产放弃协议书
- 2025年中国热镀锡铜线数据监测报告
- 母女亲子断绝协议书范本
- 物联网导论(第四版)课件:感知技术
- 客户关系管理(CRM)系统项目总结报告范文
- 抖音外卖合同协议
- 装卸设备安全管理制度
- 做有温度的护理人
评论
0/150
提交评论