目录
中断系统的原理
1.51单片机中断原理
中断系统结构见下图。中断系统有5个中断请求源(简称中断源),2个中断优先级,可实现2级中断服务程序嵌套。每一中断源可用软件独立控制为允许中断或关闭中断状态;每一个中断源的优先级均可用软件设置。
由上图,中断系统共有5个中断请求源,它们是:
(1)INT0*—外部中断请求0,外部中断请求信号(低电平或负跳变有效)由INT0*引脚输入,中断请求标志为IE0。
(2)INT1*—外部中断请求1,外部中断请求信号(低电平或负跳变有效)由INT1*引脚输入,中断请求标志为IE1。
(3)定时器/计数器T0计数溢出的中断请求,标志为TF0。
(4)定时器/计数器T1计数溢出的中断请求,标志为TF1。
(5)串行口中断请求,标志为发送中断TI或接收中断RI。
2.中断响应原理
一个中断源中断请求被响应,须满足以下必要条件:
(1)总中断允许开关接通,即IE寄存器中的中断总允许位EA=1。
(2)该中断源发出中断请求,即该中断源对应的中断请求标志为“1”。
(3)该中断源的中断允许位=1,即该中断被允许。
(4)无同级或更高级中断正在被服务。 中断响应就是CPU对中断源提出的中断请求的接受,当查询到有效的中断请求时,满足上述条件时,紧接着就进行中断响应。
中断响应过程: 首先由硬件自动生成一条长调用指令“LCALL addr16”。即程序存储区中相应的中断入口地址。例如,对于外部中断1的响应,硬件自动生成的长调用指令为:
LCALL 0013H
生成LCALL指令后,紧接着就由CPU执行该指令。首先将程序计数器PC内容压入堆栈以保护断点,再将中断入口地址装入PC,使程序转向响应中断请求的中断入口地址。各中断源服务程序入口地址是固定的,见表6-2。
其中两个中断入口间只相隔8字节,一般情况下难以安放一个完整的中断服务程序。
3.中断优先级原理
中断请求源有两个中断优先级,每一个中断请求源可由软件设置为高优先级中断或低优先级中断,也可实现两级中断嵌套。
所谓两级中断嵌套,就是AT89S51正在执行低优先级中断的服务程序时,可被高优先级中断请求所中断,待高优先级中断处理完毕后,再返回低优先级中断服务程序。
两级中断嵌套见下图。
各中断源的中断优先级关系,可归纳为下面两条基本规则:
(1)低优先级可被高优先级中断,高优先级不能被低优先级中断。
(2)任何一种中断(不管是高级还是低级)一旦得到响应,不会再被它的同级中断源所中断。如果某一中断源被设置为高优先级中断,在执行该中断源的中断服务程序时,则不能被任何其他的中断源的中断请求所中断。
4.中断标志位复位原理
在微控制器系统中,中断标志位是用来指示特定类型的中断事件是否发生。
当中断源(如外部中断、定时器溢出、接收完成等)触发时,相应的中断标志位会被设置。
中断处理程序(Interrupt Service Routine, ISR)需要检查这些标志位以确定中断的来源,并执行相应的处理逻辑。处理完成后,很关键的一步是复位(清除)这些中断标志位,以便系统可以响应后续的同类型中断。这里的复位原理涉及几个方面:
自动复位:某些微控制器的中断标志位在中断响应后会自动被硬件清零。这意味着,当中断被CPU识别并开始执行对应的ISR时,中断标志位自动清除,无需手动编程清除。
手动复位:大多数情况下,中断标志位需要在ISR中手动清除。这通常通过写特定的值到相关的寄存器来实现。复位中断标志位的方法依赖于具体的微控制器及其寄存器结构。例如,对于许多微控制器来说,可能需要向中断标志位寄存器写入`1`来清除中断标志位(写`1`清零)。
为什么需要复位中断标志位?
如果不清除中断标志位,中断服务程序完成后,中断控制逻辑可能会再次判断中断仍然有效,并再次进入相同的中断处理程序,从而形成循环,不再返回到主程序执行,导致程序卡在中断处理中。因此,正确管理中断标志位是中断编程中非常关键的一部分。
中断系统的具体应用
1.一级中断的具体应用编程
在单片机P1口上接有8只LED。在外部中断0输入引脚(P3.2)接一只按钮开关K1。要求将外部中断0设置为电平触发。程序启动时,P1口上的8只LED全亮。每按一次按钮开关K1,使引脚接地,产生一个低电平触发的外中断请求,在中断服务程序中,让低4位的LED与高4位的LED交替闪烁5次。然后从中断返回,控制8只LED再次全亮。
c语言代码
#include <reg51.h>
#define uchar unsigned char
void Delay(unsigned int i)
{
unsigned int j;
for(;i>0;i--)
{
for(j=0;j<333;j++)
{;}
}
}
void main()
{
EA=1;
EX0=1;
IT0=1;
while(1)
{
P2=0;
}
}
void int0() interrupt 0 using 0
{
uchar m;
EX0=0;
for(m