amobbs.com 阿莫电子技术论坛
标题:
发一个裸机下的界面编写方式.,,不用结构体,,设计简单,思路清晰,没有死循环,,,,使用
[打印本页]
作者:
xpstudio2003
时间:
2009-12-10 11:02
标题:
发一个裸机下的界面编写方式.,,不用结构体,,设计简单,思路清晰,没有死循环,,,,使用
发一个代码.也是本人在长期的写程序中慢慢摸索出来的,不敢说是独创..也算是原创.呵呵,,
这个代码编译不通过,,因为我只把最重要的两个文件从工程中拿了出来,,其它的就不用了,,
大体说明一下.
每个界面有一个函数.
每个界面有一个初始化函数.
每个界面有一个标记STS
点击此处下载
ourdev_512719.rar(文件大小:2K)
(原文件名:code.rar)
....
不多说了,,
个人在多个项目中使用过,稳定性很好.
没有使用那些乱七八糟的定时器,中断之类的东西,,,
作者:
AL_DWF
时间:
2009-12-10 11:26
这方法确实思路清晰,但程序大时候,占用程序空间相对较大,很多的switch
曾经用过.深有感触
作者:
xpstudio2003
时间:
2009-12-10 12:18
是啊,,一个界面一个SWITCH,
反过来想,,
无论用什么方法写,都是在一个界面里来操作按键,怎么着也得去做按键的对应处理,,,
作者:
eduhf_123
时间:
2009-12-10 12:53
MARK GUI
作者:
Gorgon_Meducer
时间:
2009-12-10 13:12
呵呵……恭喜LZ也摸索出这种模式了哈。这种工程模式我已经用很久了!不过我不使用switch,因为
局限性很大,每个状态机通常只能有一条执行线路。我使用if结构,这样每个状态机可以有多个并发
的执行线路。我注意到,你的代码中还没有使用调度器。其实配合这种状态机系统,可以用很简单的
合作式调度器来控制状态机的启动状态。有兴趣可以参考我的一些代码。
同时,配合这种编程方式,我正在酝酿一种可视化集成开发环境。哎……可惜一直没有时间实施……
作者:
AL_DWF
时间:
2009-12-10 13:26
【4楼】 Gorgon Meducer 傻孩子
"我注意到,你的代码中还没有使用调度器。其实配合这种状态机系统,可以用很简单的
合作式调度器来控制状态机的启动状态。有兴趣可以参考我的一些代码。
"
Gorgon Meducer 傻孩子
您曾写的哪个代码有用到过这种方式的?很想学习下.
作者:
astudent
时间:
2009-12-10 13:28
4楼,能否发一个按LZ所说方式、基于合作式调度器的例子?
作者:
cgbabc
时间:
2009-12-10 13:34
顶一个
作者:
astudent
时间:
2009-12-10 14:16
好贴,再顶顶!
作者:
jim166783
时间:
2009-12-10 14:33
以下是我的裸机界面,可以参考下
void (*Thrd)(void);
char InitFlag=1;
//时间设置
void TimeSet(void)
{
if(InitFlag == 1)//需要初始化界面
{
InitFlag=0;
}
if(Key == KEY_NONE)return ;
switch(Key)
{
case KEY_EXIT:
Thrd = ProcMainKey;//返回主界面
InitFlag = 1;//并需要刷新界面
break;
default:
break;
}
}
//日期设置
void DateSet(void)
{
if(InitFlag == 1)//需要初始化界面
{
InitFlag=0;
}
if(Key == KEY_NONE)return ;
switch(Key)
{
case KEY_EXIT:
Thrd = ProcMainKey;//返回主界面
InitFlag = 1;//并需要刷新界面
break;
default:
break;
}
}
//按键提示设置
void KeyToneSet(void)
{
if(InitFlag == 1)//需要初始化界面
{
InitFlag=0;
}
if(Key == KEY_NONE)return ;
switch(Key)
{
case KEY_EXIT:
Thrd = ProcMainKey;//返回主界面
InitFlag = 1;//并需要刷新界面
break;
default:
break;
}
}
void ProcMainKey(void)
{
if(InitFlag == 1)//需要初始化界面
{
InitFlag=0;
}
if(Key == KEY_NONE)return ;
switch(Key)
{
KEY1:
Thrd = TimeSet;//将“TimeSet”扔到while(1)里面循环
InitFlag = 1;
break;
KEY2:
Thrd = DateSet;//将“DateSet”扔到while(1)里面循环
InitFlag = 1;
break;
KEY3:
Thrd = KeyToneSet;//将“KeyToneSet”扔到while(1)里面循环
InitFlag = 1;
break;
default:
break;
}
}
void main(void)
{
Thrd = ProcMainKey;
while(1)
{
Thrd();
}
}
作者:
gwh1128
时间:
2009-12-10 17:46
标记下,会火
作者:
plc_avr
时间:
2009-12-10 18:19
MARK一下,谢谢。
作者:
lv998127
时间:
2009-12-10 18:34
排队学习
作者:
eddia2000
时间:
2009-12-10 18:58
[Gorgon Meducer 傻孩子]:
请把你的代码上传来看下,谢谢!
作者:
shanyan
时间:
2009-12-10 19:35
MARK
作者:
2nd090215
时间:
2009-12-10 19:57
关注下
作者:
kdtcf
时间:
2009-12-10 20:00
很好,顶
作者:
jchqxl
时间:
2009-12-10 20:22
Gorgon Meducer 傻孩子
可否把您的相关代码贴上来学习一下,谢谢。
作者:
taishandadi
时间:
2009-12-10 20:51
不错,学习经验。
作者:
cjr82123
时间:
2009-12-10 20:55
值得参考啊,谢谢!
作者:
song1km
时间:
2009-12-10 21:05
真正有价值的怎能不标。。。。。个。。记。
作者:
astudent
时间:
2009-12-10 21:32
傻孩子,都在等你!
作者:
liuweiele
时间:
2009-12-10 21:36
灵活运用C语言的 结构体 和 指针,可以达到 事半功倍 的效果~
作者:
zjr0411
时间:
2009-12-10 22:50
记号
作者:
Bird
时间:
2009-12-10 23:12
顶一个
作者:
Si_Bin
时间:
2009-12-10 23:21
偶用函数指针表....
作者:
shipingjing
时间:
2009-12-10 23:22
记号
作者:
fuanzwg
时间:
2009-12-10 23:29
mark
作者:
zhangjw
时间:
2009-12-10 23:32
mark,等傻孩子
作者:
STM32_Study
时间:
2009-12-11 00:15
等傻孩子的方案
作者:
Gorgon_Meducer
时间:
2009-12-11 09:57
我这里有两个调度器,一个是过去用的简单版本,一个是后来的改进版本,但是原理都基本一样。
这里我只说一下原理:
所有的C函数都可以看作是状态机,哪怕是一个最简单的函数,也可以看成是一个只有一个状态的
状态机。因此,最简单的状态机原型可以是大家常用的:
void FSMExample(void);
为了方便控制状态机的启动和关闭,我修改了最基本的原型:
BOOL FSMExample(void);
这就是最简单的双态状态机:
当函数返回TRUE,表明该状态机仍然“希望”处于运行状态;
当函数返回FALSE,表明该状态机已经完成,希望终止。
根据这一规定,如果通过函数指针把所有的状态机连接起来,就可以形成下面的简单调度器:
typedef struct Process
{
BOOL (*Proc)(void); //返回False,自动关闭任务
volatile BOOL IfProcAlive;
}PROCESS;
typedef BOOL (*PROC_FUNCTION)(void);
void Process_Task(void)
{
static uint8 n = 0;
if (ProcPCB[n].IfProcAlive) //处理进程
{
ProcPCB[n].IfProcAlive = (*ProcPCB[n].Proc)();
}
n ++;
if (n >= g_cCOSPROCCounter)
{
n = 0;
//g_cScheduleTest = MIN(g_cScheduleTest + 1,254);
}
}
这个调度器很简单,就是检测一个注册了的顶层状态机其Alive状态是否为TRUE,
如果为TRUE,就调用;同时在调用后将状态机的返回值重新赋给ALive属性,这样
状态机就可以通过在函数中返回TRUE或者FALSE来控制自己的运行状态。
同时,利用这一特性,状态机里面也可以调用其他子状态机,只需要在某一个状态
中调用子状态机函数并检测返回值是否为FALSE就可以知道子状态机的运行情况。
下面是一个状态机内部的例子:
#define FSM_ACTION_FLAG s_tbState.Bits
#define FSM_STOP_ALL_ACTIONS s_tbState.Value = 0;
#define FSM_START FSM_ACTION_FLAG.BIT0
#define FSM_STATE_A FSM_ACTION_FLAG.BIT1
...
BOOL FSMExampleB(void)
{
...
}
BOOL FSMExampleA(void)
{
static ES_BYTE s_tbState = {0};
if (0 == s_tbState.Value)
{
FSM_START = TRUE; //自动开始标志……
}
if (FSM_START)
{
//一些初始化操作
....
FSM_START = FALSE;
FSM_STATE_B = TRUE;
}
if (FSM_STATE_B)
{
if (!FSMExampleB()) //调用子状态机
{
//子状态机完成
...
FSM_STATE_B = FALSE;
FSM_STATE_C = TRUE; //同时激活两个状态,比如,其中一个
FSM_STATE_D = TRUE; //用于检测某个超时计数器
}
}
if (FSM_STATE_C)
{
//等待某些出发条件,比如等待某一个引脚电平为低
if (等待某个触法条件)
{
//条件触法了,比如监测到某个引脚电平为低了
... //一些操作
FSM_STATE_C = FALSE;
FSM_STATE_E = TRUE;
}
}
if (FSM_STATE_D)
{
if (检测是否超时)
{
//发生了超时
... //可以设置一些标志
FSM_STOP_ALL_ACTIONS; //复位状态机
return FALSE; //关闭状态机
}
}
if (FSM_STATE_E)
{
//假设这个状态是一个正常的终止态
...
FSM_STOP_ALL_ACTIONS;
return FALSE;
}
return TRUE;
}
使用if结构的好处是,每一个子状态都可以独立被激活,也就是可以并发激活,
对于一些明显是互斥的状态,就可以用if (){}else if (){}结构来提高效率;
同时,对于一些拥有优先级的状态,也可以用 if ... else if结构来组织。
使用这种结构,实际上可以把每一个函数看成一个 进程, 而每一个内部if结构
看成一个线程。这也符合“进程含有资源”,“线程通常不含有资源”的描述。
有兴趣的人可以发现,我的很多代码都是这种结构的。
作者:
astudent
时间:
2009-12-11 10:01
期待傻孩子更详细的论述!
作者:
jackiezeng
时间:
2009-12-11 10:12
之前我也用这种状态机的方法来编写,,,但是我后来发现使用一些简单的时间片调度系统,更方便。
作者:
Gorgon_Meducer
时间:
2009-12-11 10:13
老版本简易调度器
点击此处下载
ourdev_513080.rar(文件大小:8K)
(原文件名:FSM_EASY.rar)
新版本调度器
点击此处下载
ourdev_513081.rar(文件大小:28K)
(原文件名:FSM_V2.rar)
作者:
hisun
时间:
2009-12-11 10:17
好东西
作者:
du722
时间:
2009-12-11 16:09
mark
作者:
spely
时间:
2009-12-11 18:36
顶~
作者:
laolu
时间:
2009-12-11 18:45
不能不顶
作者:
huike
时间:
2009-12-11 20:51
MARK
作者:
hephi
时间:
2009-12-12 00:44
MARK
作者:
xpstudio2003
时间:
2009-12-12 01:38
看来我这块砖扔的还行...
作者:
t2397362
时间:
2009-12-12 08:09
好帖马克之
作者:
ndust
时间:
2009-12-12 08:18
jh
作者:
xk2yx
时间:
2009-12-12 08:27
mark
作者:
shabby
时间:
2009-12-12 08:50
记号,有时间仔细看看。
作者:
xpstudio2003
时间:
2009-12-13 11:03
参考了Gorgon Meducer 傻孩子的程序,,收获不小..
我自己改了下自己的界面程序写法.
去掉了状态变量标志.
没有改掉的是SWITCH这块,,虽然不如IF的效率高,但是直观一些,,也一直没想出来别的方法,直观但效率也要高的.
//////
以下程序仅讨论人机界面UI处理.
现在的方式是.
每个界面用一个函数来表示.
每个函数里就是处理按键.用的SWITCH方式.关于按键的产生,我在我另一个帖子里也贴出了程序.
用的函数指针来进行界面的切换.
定了了三个宏
#define UI_GOTO(index) {pUI=(index);}
#define UI_GOTO_CHILD(index) {pUI=(index); KeyDir=GOTO_CHILD;}
#define UI_GOTO_FATHER(index) {pUI=(index); KeyDir=GOTO_FATHER;}
大家不要省砖,,,俺家要盖房子.
点击此处打开
ourdev_513809.txt(文件大小:5K)
(原文件名:xpUI example.txt)
再上传我的按键处理程序
可以响应多种方式,,,KEY_DOWN KEY_HOLD KEY_BURST KEY_UP KEY_DOUBLE
用按键属性值返回.与SWITCH组合非常方便直观
点击此处下载
ourdev_513811.txt(文件大小:1K)
(原文件名:key.h.txt)
点击此处下载
ourdev_513812.txt(文件大小:6K)
(原文件名:key.c.txt)
作者:
dreampet
时间:
2009-12-13 11:24
不错 有空慢慢看
作者:
hebj
时间:
2009-12-13 11:24
学习一下。
作者:
astudent
时间:
2009-12-14 19:54
顶楼主,加盖一层楼!
作者:
quzegang
时间:
2009-12-14 20:04
Mark
作者:
feigoo
时间:
2009-12-14 21:13
MK
作者:
voidx
时间:
2009-12-18 17:59
标记。
作者:
bad_fpga
时间:
2009-12-18 19:44
mark
作者:
zhujlong
时间:
2009-12-18 19:57
mark
作者:
wangyi1e
时间:
2009-12-18 20:35
mark,学习一下!
作者:
ddcour
时间:
2009-12-18 22:52
标记!
作者:
yan_jian
时间:
2009-12-18 23:37
不错!学习了
作者:
avr-arm
时间:
2009-12-19 22:28
看了半天,我没看懂状态机,我的多层界面采用索引
//定义按键功能指针
void (*KeyFuncPtr)(void);
/*定义类型*/
typedef struct
{ unsigned int KeyStateIndex; //当前的状态索引号
void (*CurrentOperate)(void); //当前状态应该执行的功能操作
} StateTab;
/*-------------------------------------------------------------*/
StateTab KeyTab[MENU_SIZE]=
{
{1,(*main_main)},
{11,(*main_0)}, //参数设置
{12,(*main_0)}, //数据监视
{13,(*main_0)}, //关于
{14,(*main_14)}, //手动发送
{15,(*main_14_set)}, //设置为自动发送
{151,(*main_main)}, //
{141,(*hand_send)},
{111,(*main_11)}, //参数设置子菜单 主站号码
{112,(*main_11)}, //温度限定 //5
{113,(*main_11)}, //过压限定
{114,(*main_12)}, //过流限定
{115,(*main_12)}, //欠压限定
{116,(*main_12)}, //功率限定
{117,(*main_13)}, //全部默认 //10
{118,(*main_13)}, //数据存储
{119,(*main_13)}, //自动发送频率设定
{131,(*about)}, //关于子菜单
{1111,(*set_number)}, //设置主站号码
{1121,(*main_121)}, //温度限定子 //14
{1122,(*main_121)}, //wenduxianding
{11211,(*set_temph)}, //高温限定
{11221,(*set_templ)}, //低位限定
{1131,(*set_ovv)}, //过压限定设置
{1141,(*set_ovi)}, //过流设置 //19
{1151,(*set_qy)}, //欠压设置
{1161,(*set_ovw)}, //功率限定设置
{1171,(*set_default)},//默认设置
{1181,(*set_store)}, //数据存储 23
{121,(*main_21)}, //数据监视gsm
{122,(*main_21)}, //电能
{123,(*main_21)}, //开关量
{124,(*main_22)}, // 温度 27
{1221,(*main_221)},//三相电压电流
{1222,(*main_221)},//三功率 29
{1223,(*main_221)},//有功功率
{1224,(*main_224)},//无功功率
{1231,(*rd_switch)}, //开关量读取函数 31
{1211,(*main_211)}, //gsm子--at
{1212,(*main_211)}, //init
{1213,(*main_211)}, // 发信息测试 34
{12111,(*test_at)}, //at
{12121,(*test_init)}, //init
{12131,(*test_sms)}, //sms
{12211,(*axiang)},
{12221,(*abcxiang)}, //41
{12231,(*abcxiang2)},
{12241,(*abcxiang3)},
{1241,(*wendu)}, //41
{1191,(*set_auto)}, //自动发送频率设定
};
/*-------------------------------------------------------------*/
void Menu_Change(unsigned char key)
{
unsigned char i=0;
unsigned int temp;
unsigned char cengxian[5]="";
// 第一层 第二层 第三层 第四层 第五层
//unsigned char status[]={0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2d,0x20,0x2d,0x20,0x2d,0x20,0x2d,0x20};//
unsigned char status_s[] =" - - - - ";
//第一层菜单偏移为8 第二为10 第三为12 第四为14 第五为16
if(zidongesc)
{zidongesc=0;
key=Esc;
}
switch(key)
{
case UP: //向上的键
{
temp=Menu_Index-1;
for(i=0;i<MENU_SIZE;i++)
{if(temp==KeyTab
.KeyStateIndex) {Menu_Index=temp;tab_num=i;break;}
}
break;
}
case Enter: //回车键
{
temp=Menu_Index*10+1;
for(i=0;i<MENU_SIZE;i++)
{if(temp==KeyTab
.KeyStateIndex) {Menu_Index=temp;tab_num=i;break;}
}
break;
}
case Down: //向下的键
{
temp=Menu_Index+1;
for(i=0;i<MENU_SIZE;i++)
{if(temp==KeyTab
.KeyStateIndex) {Menu_Index=temp;tab_num=i;break;}
}
break;
}
case Esc: //退出键
{
temp=Menu_Index/10;
for(i=0;i<MENU_SIZE;i++)
{if(temp==KeyTab
.KeyStateIndex) {Menu_Index=temp;tab_num=i;break;}
}
break;
}
}
KeyFuncPtr=KeyTab[tab_num].CurrentOperate;
(*KeyFuncPtr)(); //执行当前的按键操作
if(key)
OSWait(K_TMO,30);
if(key||caidanxiang)
{
if(Menu_Index<=10) {cengxian[0]=Menu_Index;cengxian[1]=10;cengxian[2]=10;cengxian[3]=10;cengxian[4]=10;}
if((Menu_Index>10)&&(Menu_Index<100)) {cengxian[0]=Menu_Index/10;cengxian[1]=Menu_Index%10;cengxian[2]=10;cengxian[3]=10;cengxian[4]=10;}
if((Menu_Index>100)&&(Menu_Index<1000)) {cengxian[0]=Menu_Index/100;cengxian[1]=(Menu_Index%100)/10;cengxian[2]=Menu_Index%10;cengxian[3]=10;cengxian[4]=10;}
if((Menu_Index>1000)&&(Menu_Index<10000)) {cengxian[0]=Menu_Index/1000;cengxian[1]=(Menu_Index%1000)/100;cengxian[2]=((Menu_Index%1000)%100)/10;cengxian[3]=Menu_Index%10;cengxian[4]=10;}
if(Menu_Index>10000) {cengxian[0]=Menu_Index/10000;cengxian[1]=(Menu_Index%10000)/1000;cengxian[2]=((Menu_Index%10000)%1000)/100;cengxian[3]=(((Menu_Index%10000)%1000)%100)/10;cengxian[4]=Menu_Index%10;}
status_s[7]=cengxian[0]+48;
status_s[9]=cengxian[1]+48;
status_s[11]=cengxian[2]+48;
status_s[13]=cengxian[3]+48;
status_s[15]=cengxian[4]+48;
display_str(3,0,status_s);
caidanxiang=0;//实现首次进入餐单就刷新一次
if(!zhizhen)
{ switch ((Menu_Index%10)-1)
{
case 0:display_str(0,0,"->");display_str(1,0,"--");display_str(2,0,"--");break;
case 1:display_str(0,0,"--");display_str(1,0,"->");display_str(2,0,"--");break;
case 2:display_str(0,0,"--");display_str(1,0,"--");display_str(2,0,"->");break;
case 3:display_str(0,0,"->");display_str(1,0,"--");display_str(2,0,"--");break;
case 4:display_str(0,0,"--");display_str(1,0,"->");display_str(2,0,"--");break;
case 5:display_str(0,0,"--");display_str(1,0,"--");display_str(2,0,"->");break;
case 6:display_str(0,0,"->");display_str(1,0,"--");display_str(2,0,"--");break;
case 7:display_str(0,0,"--");display_str(1,0,"->");display_str(2,0,"--");break;
case 8:display_str(0,0,"--");display_str(1,0,"--");display_str(2,0,"->");break;
}
}
}
}
作者:
dongdaxing
时间:
2009-12-20 10:37
不错!学习了
作者:
gdourf
时间:
2009-12-20 13:45
MARK
作者:
bsz84
时间:
2009-12-20 13:46
学习,好好学习!
作者:
erxun
时间:
2009-12-20 13:54
也贴一个界面处理的函数,
根据screen_status数值来跑 。
void get_screen_status(void)
{
get_key_value(); //获取键值
/*********************运行画面响应**********************/
if(screen_status == 0x00)
{
//时间显示刷新
time_show();
if(key_Press_flag)//有键按下
{
if(key_value == Enter_key_value) //确认按下
{
chn_disp(Menu_tab); //菜单 显示
Cursor_menu = 1; //菜单光标=1,
Highlight_Cursor_menu();//菜单光标显示
screen_status = 0x01; //屏幕状态改为:菜单
}
key_value = 0; //键盘数据清除,等下下一次的操作
key_Press_flag = 0;
}
asm("nop");
}
/*********************运行响应结束*********************/
/*********************菜单画面响应**********************/
if(screen_status == 0x01)
{
if(key_Press_flag)//有键按下
{
//菜单光标处理,转移到其它画面
Cursor_menu_TAB_show();
if(key_value == Back_key_value) //返回按下
{
Highlight_Clear(); //删除所有光标
chn_disp(run_tab); //运行画面 显示
Cursor_menu = 1; //菜单光标=1,
screen_status = 0x00; //屏幕状态改为:运行
}
key_value = 0; //键盘数据清除,等下下一次的操作
key_Press_flag = 0;
}
}
/*********************菜单响应结束*********************/
/*********************瞬时值画面响应**********************/
if(screen_status == 0x02)
{
Now_value_View_show();
if(key_Press_flag)//有键按下
{
if(key_value == Back_key_value) //返回按下
{
Highlight_Clear();
chn_disp(Menu_tab); //菜单画面 显示
Highlight_Cursor_menu(); //菜单光标显示
screen_status = 0x01; //屏幕状态改为:菜单
}
Cursor_now_TAB_show(); //瞬时值光标处理
key_value = 0; //键盘数据清除,等下下一次的操作
key_Press_flag = 0;
}
}
/*********************瞬时值响应结束*********************/
/*********************历史值画面响应**********************/
if(screen_status == 0x03)
{
History_value_View_show();
if(key_Press_flag)//有键按下
{
if(key_value == Back_key_value) //返回按下
{
Highlight_Clear();
chn_disp(Menu_tab); //菜单画面 显示
Highlight_Cursor_menu(); //菜单光标显示
screen_status = 0x01; //屏幕状态改为:菜单
}
Cursor_History_TAB_show();
key_value = 0; //键盘数据清除,等下下一次的操作
key_Press_flag = 0;
}
}
/*********************历史值响应结束*********************/
/*********************历史值查询画面响应**********************/
if(screen_status == 0x06)
{
if(key_Press_flag)//有键按下
{
if(key_value == Back_key_value) //返回按下
{
chn_disp(History_tab);
Highlight_Cursor_History();
screen_status = 0x03;
}
key_value = 0; //键盘数据清除,等下下一次的操作
key_Press_flag = 0;
}
}
/*********************历史值查询响应结束*********************/
/*********************设置画面响应**********************/
if(screen_status == 0x04)
{
time_set_show(); //参数修改 显示
if(key_Press_flag)//有键按下
{
Cursor_Set_TAB_show(); //修改光标
if(key_value == Back_key_value) //返回按下
{
Highlight_Clear();
chn_disp(Menu_tab); //菜单画面 显示
Highlight_Cursor_menu(); //菜单光标显示
screen_status = 0x01; //屏幕状态改为:菜单
}
key_value = 0; //键盘数据清除,等下下一次的操作
key_Press_flag = 0;
}
}
/*********************设置响应结束*********************/
/*********************帮助画面响应**********************/
if(screen_status == 0x05)
{
if(key_Press_flag)//有键按下
{
if(key_value == Back_key_value) //返回按下
{
chn_disp(Menu_tab); //菜单画面 显示
Highlight_Cursor_menu(); //菜单光标显示
screen_status = 0x01; //屏幕状态改为:菜单
}
key_value = 0; //键盘数据清除,等下下一次的操作
key_Press_flag = 0;
}
}
/*********************帮助响应结束*********************/
}
作者:
525133174
时间:
2009-12-20 14:15
火了
mark
作者:
taishandadi
时间:
2009-12-20 14:28
此贴火了。
作者:
fy024
时间:
2009-12-20 16:31
mark
作者:
D.lovers
时间:
2009-12-20 16:51
mark.学习
作者:
wuxianglei
时间:
2009-12-21 00:25
marl
作者:
hhrfjz
时间:
2009-12-21 00:35
MARK
作者:
electricit
时间:
2009-12-21 07:58
程序当然得这么写喽,看网上人家写的GSM发短信程序,发一个while一下,发一个while一下,别的活还要不要干啦
SWITCH与IF各有千秋,
作者:
yzlyear
时间:
2009-12-21 08:34
mark
作者:
zzwuyu
时间:
2009-12-21 08:39
mark
作者:
by886
时间:
2009-12-21 09:30
先mark 慢慢学习
作者:
bigworms
时间:
2009-12-21 09:47
mark
作者:
lhj200304
时间:
2009-12-21 15:08
慢慢看,不过跟写个结构体,然后用函数指针有多大的区别?
作者:
haigerl
时间:
2009-12-21 15:28
mark
作者:
avrpicarm
时间:
2009-12-21 16:32
越简单越灵活,呵呵,
作者:
intermec
时间:
2009-12-22 21:19
LZ的例子看得不是很明白阿,哪位大大能说得具体的吗,,我太菜了,,,或是举个简单的点例子阿???
作者:
yunqian09
时间:
2009-12-22 23:41
mark
作者:
feiyang007
时间:
2009-12-23 00:22
学习了
作者:
alexmayer
时间:
2009-12-23 10:01
学习了……
作者:
mflyxy
时间:
2009-12-23 10:18
谢谢 学习
作者:
cargle
时间:
2009-12-23 10:33
很不错
作者:
lv998127
时间:
2009-12-23 10:50
标志下,准备学了
作者:
shotstar
时间:
2009-12-23 12:13
不mark不行了
作者:
wangff2531
时间:
2009-12-23 12:41
MARK GUI
作者:
TornadoYu
时间:
2009-12-23 23:30
mark~~
作者:
xyq4513
时间:
2009-12-24 10:25
mark~~
作者:
3.14159
时间:
2009-12-24 10:25
好东西
作者:
eric_wang
时间:
2009-12-24 11:45
好贴,mark!
作者:
shdzbsl
时间:
2009-12-24 12:44
mark
作者:
our_avr
时间:
2009-12-24 13:58
mark.非常好的东西啊
作者:
psl_87
时间:
2009-12-24 14:09
很不错,MARK
作者:
yaya001
时间:
2009-12-24 14:34
MARK
作者:
longfeixue
时间:
2009-12-24 15:41
慢慢学习
作者:
blueagle
时间:
2009-12-24 15:45
顶
作者:
keaiduo
时间:
2009-12-24 15:47
学习一下····
作者:
gz_dailin
时间:
2009-12-24 16:13
我也mark一下
作者:
jackmo
时间:
2009-12-24 16:54
MARK
作者:
wenwu
时间:
2009-12-24 17:09
思路不错。
作者:
wobenchentu
时间:
2009-12-24 17:17
mark.......... 学习一下
欢迎光临 amobbs.com 阿莫电子技术论坛 (https://www.amobbs.com/)
Powered by Discuz! X3.4