打印
[51单片机]

关于中断中使用局部变量

[复制链接]
5245|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
16777216|  楼主 | 2015-5-23 20:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

临时函数1()
{
uint8_t  a;
........
}

中断函数1()
{
uint8_t   b;
临时函数1()
........
}

临时函数2()
{
uint8_t  c;
........
}

中断函数2()
{
uint8_t  d;
临时函数2()

}

问题来了:
keil C51 在存储这些临时变量的时候使用外部XDATA存储,a,b,c,d 这四个临时变量有可能使用同一个XDATA地址么,如果可能,这样不就会有风险产生么?
a,c 之间明显没有调用关系,那么假设a,c使用了相同的Xdata区域,先后进入中断1,2 ,那不是会导致明显的错误么?

或者说keil怎么处理中断中的临时变量?



相关帖子

沙发
16777216|  楼主 | 2015-5-23 20:55 | 只看该作者
中断局部变量:
1.中断函数中的变量和其它函数是一样的可以使用全局变量,也可以使用局部变量。如果是局部变量,在不同中断中变量重名时是不会有影响的。
2.C51中局部变量是地址固定的,并且不互相调用的函数的局部变量地址可能是一样的。
3.中断函数的局部变量(少量)一般被分配在寄存器中,而被用到的寄存器会被压栈保护。原来的函数不会被影响。
4.C51编译程序检查所有的局部变量和所有函数的调用树,把它认为不会冲突的局部变量共用一个RAM地址,局部变量重名不会冲突,不论中断函数  还是一般函数。
5.中断中定义静态局部变量可以受到保护

使用特权

评论回复
板凳
ayb_ice| | 2015-5-24 06:57 | 只看该作者
优先为局部变量分配寄存器,其次不相互调用的函数的局部变量才可能覆盖

使用特权

评论回复
地板
16777216|  楼主 | 2015-5-24 10:44 | 只看该作者
ayb_ice 发表于 2015-5-24 06:57
优先为局部变量分配寄存器,其次不相互调用的函数的局部变量才可能覆盖

a,c 之间不是没有调用么  
编译器是怎么处理的?

使用特权

评论回复
5
huangxz| | 2015-5-24 10:54 | 只看该作者
16777216 发表于 2015-5-24 10:44
a,c 之间不是没有调用么  
编译器是怎么处理的?

局部变量被覆盖很正常,本来就是临时用的。

使用特权

评论回复
6
16777216|  楼主 | 2015-5-24 17:42 | 只看该作者
huangxz 发表于 2015-5-24 10:54
局部变量被覆盖很正常,本来就是临时用的。

中断打断时, a,c覆盖不就会出错了么

使用特权

评论回复
7
NE5532| | 2015-5-24 18:11 | 只看该作者
楼主自己做编译器的话,你会咋做?同级中断间可以共用,不同级之间只能分别用地址咯。

使用特权

评论回复
8
16777216|  楼主 | 2015-5-24 20:07 | 只看该作者
NE5532 发表于 2015-5-24 18:11
楼主自己做编译器的话,你会咋做?同级中断间可以共用,不同级之间只能分别用地址咯。 ...

下午仔细看了下中断,有点明白了。
问一下,有什么书讲这些的么,编译原理的书么?

推荐一下

使用特权

评论回复
9
NE5532| | 2015-5-24 21:45 | 只看该作者
我也不懂编译原理,我只是会写汇编,看了底层硬件结构,然后一切都了然了。看的书么,没有,就是单片机的数据手册。

使用特权

评论回复
10
16777216|  楼主 | 2015-5-24 22:09 | 只看该作者
NE5532 发表于 2015-5-24 21:45
我也不懂编译原理,我只是会写汇编,看了底层硬件结构,然后一切都了然了。看的书么,没有,就是单片机的数 ...

上次的程序由于使用using 出现莫名奇妙的错误,然后发现是寄存器组的原因,基础不牢啊。
以前上学的时候没好好学汇编。。。现在吃苦头了

使用特权

评论回复
11
ayb_ice| | 2015-5-25 07:55 | 只看该作者
16777216 发表于 2015-5-24 10:44
a,c 之间不是没有调用么  
编译器是怎么处理的?

自己看一下地址就知道了

使用特权

评论回复
12
16777216|  楼主 | 2016-2-25 20:02 | 只看该作者
ayb_ice 发表于 2015-5-25 07:55
自己看一下地址就知道了

总不能每次写程序都检查一遍吧,还是说可能会出现覆盖的情况,编译器能判断函数的中断优先级么?我觉得不能的,所以  a ,c 可能覆盖啊

使用特权

评论回复
13
myxiaonia| | 2016-2-25 22:37 | 只看该作者
当程序没有使用函数指针的话,调用树还是简单的,c51自动进行覆盖分析

使用特权

评论回复
14
datouyuan| | 2016-2-27 15:52 | 只看该作者
讲讲比较简单也比较常用的情况.
中断内用到的临时变量小于8byte,这些临时变量存在R0~R7中,发生中断后,编译器会自动生成"把中断内用到的临时变量压入堆栈中"的指令,保护现场,退出中断前,编译器会自动生成"恢复现场"的指令.

假如你只用了1byte的临时变量,编译器只会把1byte压入堆栈.

上述我都验证过.

至于你说的Xdata区域,我想编译器也会压入堆栈,保护现场.

51中函数的临时变量是编译器分配的,每次调用该函数时,临时变量的地址是固定不变的.
假如在执行该函数时,发生了中断,中断中又调用了该函数,就会发生错误.
这种情况keil会有编译警告提示.假如你能确认不可能同时发生调用该函数,你可以忽略该警告.

使用特权

评论回复
15
datouyuan| | 2016-2-27 16:05 | 只看该作者
假如该函数会被n处同时调用,你就应该有n个函数,函数内容相同,函数名不同,每处都调用一个不同的函数.

这样不会有警告,也不会出错.

使用特权

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

本版积分规则

61

主题

399

帖子

1

粉丝