xpstudio2003 发表于 2009-12-10 11:02:34

发一个裸机下的界面编写方式.,,不用结构体,,设计简单,思路清晰,没有死循环,,,,使用

发一个代码.也是本人在长期的写程序中慢慢摸索出来的,不敢说是独创..也算是原创.呵呵,,

这个代码编译不通过,,因为我只把最重要的两个文件从工程中拿了出来,,其它的就不用了,,

大体说明一下.

每个界面有一个函数.
每个界面有一个初始化函数.


每个界面有一个标记STS


点击此处下载 ourdev_512719.rar(文件大小:2K) (原文件名:code.rar)


....

不多说了,,
个人在多个项目中使用过,稳定性很好.
没有使用那些乱七八糟的定时器,中断之类的东西,,,

AL_DWF 发表于 2009-12-10 11:26:51

这方法确实思路清晰,但程序大时候,占用程序空间相对较大,很多的switch
曾经用过.深有感触

xpstudio2003 发表于 2009-12-10 12:18:02

是啊,,一个界面一个SWITCH,

反过来想,,
无论用什么方法写,都是在一个界面里来操作按键,怎么着也得去做按键的对应处理,,,

eduhf_123 发表于 2009-12-10 12:53:10

MARK GUI

Gorgon_Meducer 发表于 2009-12-10 13:12:54

呵呵……恭喜LZ也摸索出这种模式了哈。这种工程模式我已经用很久了!不过我不使用switch,因为
局限性很大,每个状态机通常只能有一条执行线路。我使用if结构,这样每个状态机可以有多个并发
的执行线路。我注意到,你的代码中还没有使用调度器。其实配合这种状态机系统,可以用很简单的
合作式调度器来控制状态机的启动状态。有兴趣可以参考我的一些代码。
同时,配合这种编程方式,我正在酝酿一种可视化集成开发环境。哎……可惜一直没有时间实施……

AL_DWF 发表于 2009-12-10 13:26:32

【4楼】 Gorgon Meducer 傻孩子
"我注意到,你的代码中还没有使用调度器。其实配合这种状态机系统,可以用很简单的
合作式调度器来控制状态机的启动状态。有兴趣可以参考我的一些代码。
"

Gorgon Meducer 傻孩子
您曾写的哪个代码有用到过这种方式的?很想学习下.

astudent 发表于 2009-12-10 13:28:57

4楼,能否发一个按LZ所说方式、基于合作式调度器的例子?

cgbabc 发表于 2009-12-10 13:34:19

顶一个

astudent 发表于 2009-12-10 14:16:16

好贴,再顶顶!

jim166783 发表于 2009-12-10 14:33:46

以下是我的裸机界面,可以参考下

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:28

标记下,会火

plc_avr 发表于 2009-12-10 18:19:20

MARK一下,谢谢。

lv998127 发表于 2009-12-10 18:34:03

排队学习

eddia2000 发表于 2009-12-10 18:58:17

:
    请把你的代码上传来看下,谢谢!

shanyan 发表于 2009-12-10 19:35:48

MARK

2nd090215 发表于 2009-12-10 19:57:31

关注下

kdtcf 发表于 2009-12-10 20:00:24

很好,顶

jchqxl 发表于 2009-12-10 20:22:34

Gorgon Meducer 傻孩子

可否把您的相关代码贴上来学习一下,谢谢。

taishandadi 发表于 2009-12-10 20:51:48

不错,学习经验。

cjr82123 发表于 2009-12-10 20:55:12

值得参考啊,谢谢!

song1km 发表于 2009-12-10 21:05:52

真正有价值的怎能不标。。。。。个。。记。

astudent 发表于 2009-12-10 21:32:32

傻孩子,都在等你!

liuweiele 发表于 2009-12-10 21:36:39

灵活运用C语言的 结构体 和 指针,可以达到 事半功倍 的效果~

zjr0411 发表于 2009-12-10 22:50:13

记号

Bird 发表于 2009-12-10 23:12:25

顶一个

Si_Bin 发表于 2009-12-10 23:21:57

偶用函数指针表....

shipingjing 发表于 2009-12-10 23:22:17

记号

fuanzwg 发表于 2009-12-10 23:29:03

mark

zhangjw 发表于 2009-12-10 23:32:41

mark,等傻孩子

STM32_Study 发表于 2009-12-11 00:15:53

等傻孩子的方案

Gorgon_Meducer 发表于 2009-12-11 09:57:50

我这里有两个调度器,一个是过去用的简单版本,一个是后来的改进版本,但是原理都基本一样。
这里我只说一下原理:
所有的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.IfProcAlive)                           //处理进程
    {
      ProcPCB.IfProcAlive = (*ProcPCB.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:15

期待傻孩子更详细的论述!

jackiezeng 发表于 2009-12-11 10:12:10

之前我也用这种状态机的方法来编写,,,但是我后来发现使用一些简单的时间片调度系统,更方便。

Gorgon_Meducer 发表于 2009-12-11 10:13:02

老版本简易调度器
点击此处下载 ourdev_513080.rar(文件大小:8K) (原文件名:FSM_EASY.rar)

新版本调度器
点击此处下载 ourdev_513081.rar(文件大小:28K) (原文件名:FSM_V2.rar)

hisun 发表于 2009-12-11 10:17:43

好东西

du722 发表于 2009-12-11 16:09:24

mark

spely 发表于 2009-12-11 18:36:31

顶~

laolu 发表于 2009-12-11 18:45:17

不能不顶

huike 发表于 2009-12-11 20:51:23

MARK

hephi 发表于 2009-12-12 00:44:42

MARK

xpstudio2003 发表于 2009-12-12 01:38:48

看来我这块砖扔的还行..../emotion/em025.gif./emotion/em025.gif./emotion/em025.gif./emotion/em025.gif

t2397362 发表于 2009-12-12 08:09:33

好帖马克之

ndust 发表于 2009-12-12 08:18:14

jh

xk2yx 发表于 2009-12-12 08:27:57

mark

shabby 发表于 2009-12-12 08:50:08

记号,有时间仔细看看。

xpstudio2003 发表于 2009-12-13 11:03:52

参考了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_UPKEY_DOUBLE
用按键属性值返回.与SWITCH组合非常方便直观



点击此处下载 ourdev_513811.txt(文件大小:1K) (原文件名:key.h.txt)
点击此处下载 ourdev_513812.txt(文件大小:6K) (原文件名:key.c.txt)

dreampet 发表于 2009-12-13 11:24:00

不错 有空慢慢看

hebj 发表于 2009-12-13 11:24:44

学习一下。

astudent 发表于 2009-12-14 19:54:49

顶楼主,加盖一层楼!

quzegang 发表于 2009-12-14 20:04:40

Mark

feigoo 发表于 2009-12-14 21:13:51

MK

voidx 发表于 2009-12-18 17:59:09

标记。

bad_fpga 发表于 2009-12-18 19:44:39

mark

zhujlong 发表于 2009-12-18 19:57:25

mark

wangyi1e 发表于 2009-12-18 20:35:12

mark,学习一下!

ddcour 发表于 2009-12-18 22:52:04

标记!

yan_jian 发表于 2009-12-18 23:37:42

不错!学习了

avr-arm 发表于 2009-12-19 22:28:37

看了半天,我没看懂状态机,我的多层界面采用索引
//定义按键功能指针
void (*KeyFuncPtr)(void);         

/*定义类型*/
typedef struct
{unsigned int KeyStateIndex;   //当前的状态索引号
   void (*CurrentOperate)(void);      //当前状态应该执行的功能操作
}StateTab;

/*-------------------------------------------------------------*/
StateTab KeyTab=
{
   {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="";

                         //                                     第一层   第二层    第三层    第四层    第五层
//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)
        {
          caseUP:                     //向上的键
                {
                   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;
                }
                caseDown:                          //向下的键
                {
                        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.CurrentOperate;

        (*KeyFuncPtr)();   //执行当前的按键操作
        if(key)
        OSWait(K_TMO,30);
        if(key||caidanxiang)
{
        if(Menu_Index<=10) {cengxian=Menu_Index;cengxian=10;cengxian=10;cengxian=10;cengxian=10;}
        if((Menu_Index>10)&&(Menu_Index<100)) {cengxian=Menu_Index/10;cengxian=Menu_Index%10;cengxian=10;cengxian=10;cengxian=10;}
    if((Menu_Index>100)&&(Menu_Index<1000)) {cengxian=Menu_Index/100;cengxian=(Menu_Index%100)/10;cengxian=Menu_Index%10;cengxian=10;cengxian=10;}
    if((Menu_Index>1000)&&(Menu_Index<10000)) {cengxian=Menu_Index/1000;cengxian=(Menu_Index%1000)/100;cengxian=((Menu_Index%1000)%100)/10;cengxian=Menu_Index%10;cengxian=10;}
    if(Menu_Index>10000) {cengxian=Menu_Index/10000;cengxian=(Menu_Index%10000)/1000;cengxian=((Menu_Index%10000)%1000)/100;cengxian=(((Menu_Index%10000)%1000)%100)/10;cengxian=Menu_Index%10;}
        status_s=cengxian+48;
        status_s=cengxian+48;
        status_s=cengxian+48;
        status_s=cengxian+48;
        status_s=cengxian+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:10

不错!学习了

gdourf 发表于 2009-12-20 13:45:50

MARK

bsz84 发表于 2009-12-20 13:46:31

学习,好好学习!

erxun 发表于 2009-12-20 13:54:06

也贴一个界面处理的函数,
根据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:35

火了
mark

taishandadi 发表于 2009-12-20 14:28:59

此贴火了。

fy024 发表于 2009-12-20 16:31:15

mark

D.lovers 发表于 2009-12-20 16:51:49

mark.学习

wuxianglei 发表于 2009-12-21 00:25:39

marl

hhrfjz 发表于 2009-12-21 00:35:53

MARK

electricit 发表于 2009-12-21 07:58:06

程序当然得这么写喽,看网上人家写的GSM发短信程序,发一个while一下,发一个while一下,别的活还要不要干啦
SWITCH与IF各有千秋,

yzlyear 发表于 2009-12-21 08:34:47

mark

zzwuyu 发表于 2009-12-21 08:39:45

mark

by886 发表于 2009-12-21 09:30:15

先mark 慢慢学习

bigworms 发表于 2009-12-21 09:47:40

mark

lhj200304 发表于 2009-12-21 15:08:33

慢慢看,不过跟写个结构体,然后用函数指针有多大的区别?

haigerl 发表于 2009-12-21 15:28:30

mark

avrpicarm 发表于 2009-12-21 16:32:06

越简单越灵活,呵呵,

intermec 发表于 2009-12-22 21:19:49

LZ的例子看得不是很明白阿,哪位大大能说得具体的吗,,我太菜了,,,或是举个简单的点例子阿???

yunqian09 发表于 2009-12-22 23:41:08

mark

feiyang007 发表于 2009-12-23 00:22:19

学习了

alexmayer 发表于 2009-12-23 10:01:49

学习了……

mflyxy 发表于 2009-12-23 10:18:00

谢谢学习

cargle 发表于 2009-12-23 10:33:23

很不错

lv998127 发表于 2009-12-23 10:50:09

标志下,准备学了

shotstar 发表于 2009-12-23 12:13:43

不mark不行了

wangff2531 发表于 2009-12-23 12:41:16

MARK GUI

TornadoYu 发表于 2009-12-23 23:30:30

mark~~

xyq4513 发表于 2009-12-24 10:25:09

mark~~

3.14159 发表于 2009-12-24 10:25:45

好东西

eric_wang 发表于 2009-12-24 11:45:20

好贴,mark!

shdzbsl 发表于 2009-12-24 12:44:33

mark

our_avr 发表于 2009-12-24 13:58:47

mark.非常好的东西啊

psl_87 发表于 2009-12-24 14:09:38

很不错,MARK

yaya001 发表于 2009-12-24 14:34:12

MARK

longfeixue 发表于 2009-12-24 15:41:04

慢慢学习

blueagle 发表于 2009-12-24 15:45:22

keaiduo 发表于 2009-12-24 15:47:05

学习一下····

gz_dailin 发表于 2009-12-24 16:13:30

我也mark一下

jackmo 发表于 2009-12-24 16:54:09

MARK

wenwu 发表于 2009-12-24 17:09:04

思路不错。

wobenchentu 发表于 2009-12-24 17:17:42

mark.......... 学习一下
页: [1] 2 3 4 5 6
查看完整版本: 发一个裸机下的界面编写方式.,,不用结构体,,设计简单,思路清晰,没有死循环,,,,使用