关于51堆栈大小的算法求助

[复制链接]
1487|8
手机看帖
扫描二维码
随时随地手机跟帖
18576478035|  楼主 | 2018-12-8 11:00 | 显示全部楼层 |阅读模式
求助51单片机的堆栈大小的算法,如果主程序中发生多级函数调用,比如说10层函数调用,此时进入一个中断(使用同一个寄存器组),堆栈大小是多大?10*2+15=35是这样吗?如果在进入中断中被另外一个中断优先级打断,此时的堆栈大小是多大?10*2+15+15?是这样吗?如果我的堆栈只有40个字节的话要怎么避免堆栈溢出的现象?????我在中断里面加上EA=0暂时关闭全局中断是不是可以避免堆栈溢出?

相关帖子

18576478035|  楼主 | 2018-12-8 11:18 | 显示全部楼层
有人知道吗?

使用特权

评论回复
18576478035|  楼主 | 2018-12-8 11:21 | 显示全部楼层
求助大佬

使用特权

评论回复
datouyuan| | 2018-12-8 11:33 | 显示全部楼层
本帖最后由 datouyuan 于 2018-12-8 11:37 编辑

你这估算是正确的。
中断里面加上EA=0,不好。假如怕被打断,把所有中断的嵌入优先等级设为一样的,就不会打断了。不特别设置,默认所有中断的嵌入优先等级是一样的。

使用特权

评论回复
john_lee| | 2018-12-8 15:54 | 显示全部楼层
51 有4个寄存器BANK,如果程序使用的中断数量<=3个,可以把每个中断使用的寄存器安排到不同的BANK中,这样就可以不用关闭全局中断了。

使用特权

评论回复
18576478035|  楼主 | 2018-12-8 16:18 | 显示全部楼层
datouyuan 发表于 2018-12-8 11:33
你这估算是正确的。
中断里面加上EA=0,不好。假如怕被打断,把所有中断的嵌入优先等级设为一样的,就不会 ...

为什么中断不能用EA等于0 ,芯片手册上写的每一个中断源都可以通过各自的中断使能位开启或关闭,这些位在IE和EIE特殊功能寄存器SFRs中。有一个全局
使能中断EA(IE.7)位,清0将关闭所有中断,置位启用已单独使能了的中断,清0不管单独的中断源,是否使能了
都关闭所有中断。注意:当EA为0时有中断请求,所有中断会被挂起直到EA恢复为1,才去执行该中断。所有中
断标志位可以用软件置位,也可以用软件启动中断。在EA= 0的时候如果有中断产生的话等出中断服务函数也会去执行新的中断,不会出现问题吧?

使用特权

评论回复
linqing171| | 2018-12-8 22:41 | 显示全部楼层
你低优先级的中断里EA=0之前,汇编已经把堆栈压了不少了,此时如果来了高优先级的,还是没有用。
keil c51是整个中断入口的所有调用树,用到的寄存器,都给你压堆栈保存了。

用using后缀切换psw,那么它调用的函数里面要么也切psw,要么不让使用寄存器别名(AR0这种)。操作起来也麻烦。

我感觉把中断做的非常简单,只记录标志位。处理在main里面,这样堆栈用的少。

使用特权

评论回复
ayb_ice| | 2018-12-10 08:50 | 显示全部楼层
嵌套调用的堆栈一般10层够用了,占用20个字节,然后就是中断寄存器保护最多13个字节(A,B,PSW,DPH,DPL,R0~R7),考虑到两级嵌套13*2+20=46,留64字节够保险了

使用特权

评论回复
datouyuan| | 2018-12-10 17:44 | 显示全部楼层
18576478035 发表于 2018-12-8 16:18
为什么中断不能用EA等于0 ,芯片手册上写的每一个中断源都可以通过各自的中断使能位开启或关闭,这些位在 ...

既然你不需要任何中断被打断,比较好的方法是还是使所有中断的嵌入优先级相同。

当然你这种方法也能用。

使用特权

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

本版积分规则

55

主题

187

帖子

2

粉丝