打印

IAR 环境中断函数中不能使用goto语句

[复制链接]
6862|20
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
paulsimons|  楼主 | 2010-5-18 21:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
ayb_ice| | 2010-5-19 08:51 | 只看该作者
本帖最后由 ayb_ice 于 2010-5-19 08:52 编辑

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

使用特权

评论回复
板凳
zq1987731| | 2010-5-19 09:36 | 只看该作者
本帖最后由 zq1987731 于 2010-5-19 23:05 编辑

LZ的C基本语法需要加强一下

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

ISP()
{
    if(...)
        goto program1;
    if(....)
        goto program2;
}

使用特权

评论回复
地板
zq1987731| | 2010-5-19 09:40 | 只看该作者
中断里用goto,当然可以,但你对自己的做法代表的含义以及可能产生的一切后果还不清楚的话就别这么用
宁可在中断里对一个声明为volatile的全局变量进行赋值操作,再回到主程序中根据该值跳转到相应程序处

使用特权

评论回复
5
paulsimons|  楼主 | 2010-5-19 20:17 | 只看该作者
我意思是直接goto 出中断函数,到我要操作的函数,应为我的应用要求立即跳转,在主函数中的循环时间很长,如果用全局变量的话,会等很久的,有没有好的办法,谢谢

使用特权

评论回复
6
zq1987731| | 2010-5-19 22:13 | 只看该作者
LZ用汇编写过程序,就应该明白
当你进入中断服务程序时,单片机本身会备份当前程序状态,中断部分执行完毕后会用RETI恢复现场
如果这时候主程序是在执行一个子程序时进入的中断,那么中断执行完毕后自然会继续执行之前的子程序毫无影响,问题就在这...中断部分用LJMP之类跳转指令(相当于goto),自然是“合法”得跳转到目的地,但之前被执行到一半的子程序将会被彻底打断,程序架构一旦没处理好这部分,出问题也在所难免,比如一个状态机,在状态改变时的那一步被打断......
这样的话,要么你在所有不可打断处关闭中断,处理完毕后再打开,但这样程序可移植性等等都将被破坏
要么用类似如下主循环:
while(1)
{
    工作1;
        跳转变量检测;
    工作2;
        跳转变量检测;
    工作3;
        跳转变量检测;
    工作4;
        跳转变量检测;
    ....
}
这样看似语句啰嗦不少,但每次大循环也就牺牲若干个微秒便可保证响应的速度

使用特权

评论回复
7
原野之狼| | 2010-5-19 23:00 | 只看该作者
3楼已经解决了你的语法问题
这样写程序的思路是不可取的
从软件结构上再多做些考虑

使用特权

评论回复
8
ershisi| | 2010-5-19 23:05 | 只看该作者
goto语句本来就不提倡使用

使用特权

评论回复
9
ayb_ice| | 2010-5-20 09:09 | 只看该作者
没有办法,对xx弹琴

使用特权

评论回复
10
icecut| | 2010-5-20 09:25 | 只看该作者
哈哈,幸亏iar聪明。新手不要用goto

使用特权

评论回复
11
yyydddccc| | 2010-5-20 11:13 | 只看该作者
学习学习

使用特权

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

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

}

使用特权

评论回复
13
ayb_ice| | 2010-5-20 11:52 | 只看该作者
LZ竟还没有搞清楚RETI与RET区别

使用特权

评论回复
14
paulsimons|  楼主 | 2010-5-20 11:57 | 只看该作者
LZ竟还没有搞清楚RETI与RET区别
ayb_ice 发表于 2010-5-20 11:52


你意思是这种方法行不通,必须用flag咯?

使用特权

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

使用特权

评论回复
16
mcu5i51| | 2010-5-20 15:37 | 只看该作者
可以使用,不过你必须恢复现场比如
main()
{
program1:
F1()
goto isrexit;
  {.....}

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

}

ISP
{
if(...)
    goto F1

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

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

使用特权

评论回复
17
ayb_ice| | 2010-5-20 15:49 | 只看该作者
LS
请问RETI怎么办,当然你可以说用汇编
这根本就是不懂中断

使用特权

评论回复
18
LIUXRUI2010| | 2013-5-24 16:29 | 只看该作者
paulsimons 发表于 2010-5-20 11:43
还是和你们解释一下吧,不是语法的问题,是流程问题,这个程序很简单,我的意思是每个函数执行时间很长(而 ...

楼主这种思想最后有没有想到好的办法,我也想跳出原来的函数

使用特权

评论回复
19
技美电子| | 2013-5-24 16:48 | 只看该作者
楼上说了这么多,楼主的思想还没有得到改变!悲催!

使用特权

评论回复
20
dld2| | 2013-5-24 16:58 | 只看该作者

使用特权

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

本版积分规则

29

主题

67

帖子

0

粉丝