首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

[推荐]实现51单片机中断的递归

[推荐]实现51单片机中断的递归

本来51单片机是不支持中断服务程序的递归的,但是,分析51单片机中断机理,得出不能递归的原因,具体问题具体解决,从而使51具备中断递归的条件。

我们知道,子程序调用LCALL指令实现了对下一条指令的PCH和PCL的压栈,中断服务程序实际上是在暗地里执行了一个LCALL指令,则也对下一条指令的PCH和PCL实现压栈,但是,与编程指令LCALL不同的是,中断服务程序还置位内部一个不可访问的中断优先级阻挡触发器,这个触发器我们不知道在什么地方,没有给出位地址,总之他存在着,并且现在被置位为1了,只要为1,就能禁止同级中断源的再入,包括自身的中断源。

指令RET实现对PCL和PCH的堆栈弹出,与LCALL指令相对应,一个是之程序调用,一个是子程序返回,他们是成对出现的。而指令RETI也实现对PCL和PCH的堆栈弹出,与中断服务程序相对应;但是,RETI指令与RET指令所不同的是,RETI除了实现对PCL和PCH的堆栈弹出外,还清除内部一个不可访问的中断优先级阻挡触发器,以便重新允许同级中断的中断,包括自身中断源。

当我们了解了LCALL\中断服务\RET\RETI\以后,我们如何通过编程,才能实现中断的递归呢?即不退出中断服务程序,能使同级或低级当然包括高级中断服务程序的再次中断呢。

回答是:在某中断服务程序中,一开始首先调用一个空的子程序,这个空子程序有个特征,就是只有一条指令,即返回指令,但不是RET,而是RETI,执行这条指令后,既从子程序返回到中断服务程序中来了,又清除了那个不可访问的中断优先级阻挡触发器,从而实现再来同级或低级(包括高级)中断信号的时候,能打断正在执行的中断服务程序,这就实现了中断服务程序的递归了。而本中断服务程序的最后的返回指令,是RET还是RETI已经不重要了。

活到老学到老永不满足
返回列表