打印

条件编译问题,如何从当前的函数跳转到主函数?

[复制链接]
4947|22
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
开始的梦想|  楼主 | 2010-7-29 17:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
程序运行后,执行 Open_Lock()或者 psw_change()时,只要当flag_tz=0时,怎样从当前运行的函数中回到主程序呢?程序如下:
void main()
{
  while (1)
  {
     dis_Ds1302();   
     switch (getpsw())
      {
      case 0:
              Open_Lock();   
              delay1(50);   
               break;
      case 1:
              psw_change();  
              delay1(50);
              break;
      case 2:
              dis_again();  
              delay1(50);
              break;
      case 3:
             flag_tz=0;  //返回
             break;   
     default: break;
     }
  }
}

相关帖子

沙发
程序匠人| | 2010-7-29 17:40 | 只看该作者
“当前运行的函数”是指Open_Lock()和 psw_change()吗?

使用特权

评论回复
板凳
开始的梦想|  楼主 | 2010-7-29 17:50 | 只看该作者
是呀,只要满足flag_tz=0时,程序就跳转回主程序,好像不能用goto。。。

使用特权

评论回复
地板
程序匠人| | 2010-7-29 17:59 | 只看该作者
我想不出在什么情况下,会有你这种需求。

从下一级程序往上一级程序跳,是“**”啊。

先学习一下模块化编程的理念,而不是具体的小技巧。

用正确的技巧去实现一个错误的理念。无益!

使用特权

评论回复
5
程序匠人| | 2010-7-29 18:00 | 只看该作者
敏感字了:L

使用特权

评论回复
6
大道至简| | 2010-7-29 18:20 | 只看该作者
执行一个软复位指令自然就到main函数去执行了

使用特权

评论回复
7
hotpower| | 2010-7-30 06:52 | 只看该作者
while(1)改为while(flag_tz)

使用特权

评论回复
8
hotpower| | 2010-7-30 06:52 | 只看该作者
while(1)改为while(flag_tz)

使用特权

评论回复
9
McuPlayer| | 2010-7-30 08:00 | 只看该作者
flag_tz对Open_Lock()或者 psw_change()内部是不可见的,你怎么判断
做参数送进去或者改成全局的

使用特权

评论回复
10
流行音乐| | 2010-7-30 10:05 | 只看该作者
从楼主的程序和提出的要求来看,可以换一种实现方法,即直接把   dis_Ds1302(); 放到中断函数中,并想办法让 flag_tz 触发该中断即可。

使用特权

评论回复
11
seefront| | 2010-7-30 11:44 | 只看该作者
首先同意4楼说的,建议再考虑一下模块设计。

对这样的需求,我的主意和9楼差不多,把flag_tz做成全局变量或者当成参数送进函数(用指针传递),然后在那两个函数体内部循环判断这个参数的值,举个例子:
全局变量方式:
int flag_tz = 1;
然后在Open_Lock()和 psw_change()里加上这样的循环:
while(flag_tz)
{
       //TODO: Your code here
}


用参数传递方式:
Open_Lock(int *flag);
psw_change(int *flag);

void main()
{
      int flag_tz = 1;

       // 调用函数的地方
    Open_Lock(&flag_tz);
      psw_change(&flag_tz);
}

在Open_Lock()和 psw_change()中加入循环检测:
while(*flag)
{
      //do somgthing
}

使用特权

评论回复
12
开始的梦想|  楼主 | 2010-7-30 13:23 | 只看该作者
我的程序其实也不是很复杂的,一个密码锁程序,就是上电后显示时钟,然后等待键盘的操作 ,并根据按键值执行相应的程序,当按下开锁键后执行Open_Lock(),按下修改密码键后执行psw_change()。。等,程序执行完后回到主程序,显示时钟。
   但是,假如在执行Open_Lock()或 psw_change()中,只要按下返回键后(标志位flag_tz),就能从当前执行的程序中回到主程序,显示时钟。
  谢谢楼上各位的建议!!!

使用特权

评论回复
13
linbei1988| | 2010-7-30 14:45 | 只看该作者
正在执行open_lock()或psw_change()时碰到返回键,就不继续执行下去,而是直接返回了?
不符合密码锁的要求吧

使用特权

评论回复
14
xymxym| | 2010-7-30 15:02 | 只看该作者
我猜:
在Open_Lock()或psw_change()时,显示屏会显示“锁已开”或者“密码修改”等信息,而且这个显示可能会停留一会儿,才会返回去显示待机状态时的时钟,或者按返回键直接就回去。要实现的功能应该是这样吧?
我怀疑:
你在执行一种动作时候,是一直呆在那个功能函数不出来,比如执行Open_Lock()时,直到显示“锁已开”的停留时间到了,才退出这个函数。
这样做:
执行Open_Lock(),只在里面设置一些必要的参数,该用定时中断还得用,切勿在里面呆太久,然后就回到主循环,键盘扫描和处理程序在主循环中,当是返回键时,重置相关参数,关闭定时器等。

使用特权

评论回复
15
cbs110| | 2010-7-30 16:14 | 只看该作者
同10楼,你可以将返回键作为外部中断的按键,将dis_Ds1302()放在外部中断中处理,即当返回键按下后,进行外部中断处理,主程序中只需对getpsw()做判断就可以。

使用特权

评论回复
16
开始的梦想|  楼主 | 2010-7-30 17:02 | 只看该作者
同10楼,你可以将返回键作为外部中断的按键,将dis_Ds1302()放在外部中断中处理,即当返回键按下后,进行外部中断处理,主程序中只需对getpsw()做判断就可以。

回cbs110:

  将返回键作为外部中断按键行不通的,因为硬件限制了,键盘采用的是矩阵,返回键作为其中功能键之一。
  另外将dis_Ds1302()放在中断中处理可能行不通,首先dis_Ds1302()子函数比较大,里面还包含调整时钟功能,放在中断里面不合适,其次两个定时中断也用了,一个用于蜂鸣器报警,另一个用于dis_Ds1302()函数。

使用特权

评论回复
17
流行音乐| | 2010-7-30 17:02 | 只看该作者
本帖最后由 流行音乐 于 2010-7-30 17:10 编辑
我的程序其实也不是很复杂的,一个密码锁程序,就是上电后显示时钟,然后等待键盘的操作 ,并根据按键值执行相应的程序,当按下开锁键后执行Open_Lock(),按下修改密码键后执行psw_change()。。等,程序执行完后回到 ...
开始的梦想 发表于 2010-7-30 13:23

这个问题用分时处理的方法就能轻松解决。

使用特权

评论回复
18
开始的梦想|  楼主 | 2010-7-30 17:37 | 只看该作者
我猜:
在Open_Lock()或psw_change()时,显示屏会显示“锁已开”或者“密码修改”等信息,而且这个显示可能会停留一会儿,才会返回去显示待机状态时的时钟,或者按返回键直接就回去。要实现的功能应该是这样吧?
我怀疑:
你在执行一种动作时候,是一直呆在那个功能函数不出来,比如执行Open_Lock()时,直到显示“锁已开”的停留时间到了,才退出这个函数。
这样做:
执行Open_Lock(),只在里面设置一些必要的参数,该用定时中断还得用,切勿在里面呆太久,然后就回到主循环,键盘扫描和处理程序在主循环中,当是返回键时,重置相关参数,关闭定时器等。

xymxym发表于 2010-7-30 15:02
“我猜”和“我怀疑”和我的想法简直是一样的,呵呵!

使用特权

评论回复
19
冷漠| | 2010-7-30 19:02 | 只看该作者
本帖最后由 冷漠 于 2010-7-31 11:40 编辑

按下“返回键”是一个异步事件,CPU必然反应!没有说CPU忙不过来就不理会键盘输入的。——即使是矩阵键盘,按下任意键也会拉低行扫描线;
        所以把行扫描线接到外部中断INT0 / INT1即可。现在的51系列兼容单片机几乎都是整个P1端口8个I/O 输入脚全部能够触发中断,拿出一个来做返回键触发中断何妨?例如华邦W78E58之类。

然后用汇编写一个中断按键处理程序,例如TT2_INT0:
NAME  TT2_INT0

        EXTRN  DATA(spa)
        EXTRN  CODE(main)
CSEG        AT        00003H   ;假设外部中断0
        LJMP        isr0
; }
; void isr0(void) interrupt 0   using  1   

isr0:
        USING        1        ; SOURCE LINE # 16
; {
        ..........
         ;(your  code.....)

        ...........
;下面语句 返回到Main()主函数程序起始点。
;   SP=spa;
        MOV          SP,spa
; DPTR=main;
       MOV          DPTR,#main
; _push_(DPH);
       PUSH         DPH
; _push_(DPL);
       PUSH         DPL
; }
        RETI         
; END OF isr0
        END


当然主函数main ( )中有下列语句:例如:

char  spa;
main()
{
spa=SP;

……
  }

使用特权

评论回复
20
xuyiyi| | 2010-7-30 19:41 | 只看该作者
搞的那么复杂干嘛?
只要在主程序调用的子程序中设个状态位即可,状态不改变不返回,进入子程序死循环;状态一改变立马返回主程序。
程序还是请多考虑用模块化结构,便于今后的修改和移植。
在复杂的多条件、多变量判断程序中,请多考虑用状态转移法编程,结构简洁干净,思路清晰,利于扩展功能。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

58

帖子

1

粉丝