根据中断中的判断,直接跳转到对应的地方,如何实现?

[复制链接]
907|28
手机看帖
扫描二维码
随时随地手机跟帖
hanwe|  楼主 | 2019-7-13 13:49 | 显示全部楼层 |阅读模式

main()
{
program1:
F1()
    {.....}

program2:
F2()
    {.....}

}

ISP
{
if(...)
      goto F1

if(....)
    goto F2
}

根据中断中的判断,直接跳转到对应的地方,如何实现?

使用特权

评论回复
yufe| | 2019-7-13 13:57 | 显示全部楼层

不是不可以用GOTO,是你用错了,幸好IAR比你聪明
这是当然的
即使可以编译,运行也会出错的
中断返回RETI和子程序返回返回RET是不同的

使用特权

评论回复
llia| | 2019-7-13 14:02 | 显示全部楼层
LZ的C基本语法需要加强一下main()

{

program1:    F1()

                    {.....}

program2:    F2()

                    {.....}

}



ISP()

{

    if(...)

        goto program1;

    if(....)

        goto program2;

}

使用特权

评论回复
llia| | 2019-7-13 14:05 | 显示全部楼层
中断里用goto,当然可以,但你对自己的做法代表的含义以及可能产生的一切后果还不清楚的话就别这么用

使用特权

评论回复
wangzsa| | 2019-7-13 14:09 | 显示全部楼层


宁可在中断里对一个声明为volatile的全局变量进行赋值操作,再回到主程序中根据该值跳转到相应程序处

使用特权

评论回复
hanwe|  楼主 | 2019-7-13 14:13 | 显示全部楼层
我意思是直接goto 出中断函数,到我要操作的函数,应为我的应用要求立即跳转,在主函数中的循环时间很长,如果用全局变量的话,会等很久的,有没有好的办法,谢谢

使用特权

评论回复
zhanglli| | 2019-7-13 14:16 | 显示全部楼层

LZ用汇编写过程序,就应该明白
当你进入中断服务程序时,单片机本身会备份当前程序状态,中断部分执行完毕后会用RETI恢复现场
如果这时候主程序是在执行一个子程序时进入的中断,那么中断执行完毕后自然会继续执行之前的子程序毫无影响,问题就在这...中断部分用LJMP之类跳转指令(相当于goto),自然是“合法”得跳转到目的地,但之前被执行到一半的子程序将会被彻底打断,程序架构一旦没处理好这部分,出问题也在所难免

使用特权

评论回复
lium| | 2019-7-13 14:29 | 显示全部楼层


goto语句本来就不提倡使用

使用特权

评论回复
hanwe|  楼主 | 2019-7-13 14:32 | 显示全部楼层
还是和你们解释一下吧,不是语法的问题,是流程问题,这个程序很简单,我的意思是每个函数执行时间很长(而且你面包含很多外部函数)如果设置flag会有延迟,希望中断中通过判断直接跳转到要执行的函数,我希望知道这种架构能否实现,这是我临时敲的语法错误请忽略,谢谢

main()
{
//初始化,省略。。。
while(1)
{
      F1()    //这个函数是大概运行时间是3分钟
       {.......}
      F2()    //这个函数是大概运行时间是3分钟
       {.......}
      F3()    //这个函数是大概运行时间是3分钟
       {.......}
}
ISP
{
if(情况1)
    goto F1;
if(情况2)
    goto F2;
if(情况3)
   goto F3;
}
      

}

使用特权

评论回复
lium| | 2019-7-13 14:39 | 显示全部楼层
LZ竟还没有搞清楚RETI与RET区别

使用特权

评论回复
hanwe|  楼主 | 2019-7-13 14:41 | 显示全部楼层
你意思是这种方法行不通,必须用flag咯?

使用特权

评论回复
llia| | 2019-7-13 14:44 | 显示全部楼层

中断必须用RETI返回,只有声明为中断属性的函数编译器才会编译成用RETI指令返回,而F1~F3编译器会用RET返回,你说会不会出错,
你那样中断立马出错,要么同级和低级中断被屏蔽,要么返回到火星上去了(成了外星人了),这取决于内核架构
...
但汇编可以...

使用特权

评论回复
wangpe| | 2019-7-13 14:49 | 显示全部楼层

可以使用,不过你必须恢复现场比如
main()
{
program1:
F1()
goto isrexit;
    {.....}

program2:
F2()
goto isrexit;
    {.....}

}

ISP
{
if(...)
      goto F1

if(....)
    goto F2
isrexit:
}

因为会跳过很多数据初始化,以及变量覆盖的存在,因此出问题的可能相当高,尽量不用,或做好数据处理后用

使用特权

评论回复
wangzsa| | 2019-7-13 14:55 | 显示全部楼层


LS
请问RETI怎么办

使用特权

评论回复
zhuww| | 2019-7-13 14:57 | 显示全部楼层


当然你可以说用汇编
这根本就是不懂中断

使用特权

评论回复
zhanglli| | 2019-7-13 15:00 | 显示全部楼层

楼主其实最想问的是函数调度问题,那你也要分优先级啊。并且在函数中运行,你就设置一个忙的标志位,置这次的中断无效。

使用特权

评论回复
lium| | 2019-7-13 15:08 | 显示全部楼层

其实对于这种问题,楼主可以使用状态机,将那些要运行几分钟的任务分解掉,然后查询变量,或者更复杂的就上操作系统

使用特权

评论回复
guoyt| | 2019-7-13 15:13 | 显示全部楼层
首先:goto不能跨函数跳跃。
你想呀,函数调用时,编译器会对入口地址啊,函数参数啊之类的做入栈处理,然后你说进入子函数后要无条件goto回去,你这不让编译器幸幸苦苦搬运了一大堆堆栈数据的劳动白费了么!还有,你这样来几次,不是把堆栈往死里赶么?!

其次:每中断一次,你就要去处理一个3分钟的事情,那么你的中断周期必须大于3分钟,否则就比半夜**叫的周扒皮还苛刻了,处理器根本就忙不过来的。所以,如果你必须按你提供的代码那么处理,那就把你那3分钟的事情放到中断去处理吧(想想就可怕,3分钟那么长时间的谢绝打扰,会把外设逼疯的!)。

使用特权

评论回复
yufe| | 2019-7-13 15:17 | 显示全部楼层

最后:最好还是把你那3分钟执行时间的函数给打散吧。
一个函数从入口到出口要3分钟,除非有操作系统做调度,不然会让其余函数等得望穿秋水的。

使用特权

评论回复
guoyt| | 2019-7-13 15:20 | 显示全部楼层
不建议使用GOTO语句,尤其是在中断里不要用。

使用特权

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

本版积分规则

979

主题

8749

帖子

4

粉丝