一、单片机中断系统的概念
什么是中断,我们从一个生活中的例程引入。
你正在家中看书,突然电话铃响了(中断发生),你放下书本,去接电话,和来电话的人交谈(中断响应和中断服务),然后放下电话,回来继续看你的书(中断返回)。这就是生活中的“中断”的现象,就是正常的工作过程被外部的事件打断了。仔细研究一下生活中的中断,对于我们学习单片机的中断也很有好处。
中断响应和处理过程:
能够实现中断处理功能的部件称为中断系统;产生中断的请求源称为中断请求源。
中断源向CPU提出的处理请求,称为中断请求(或中断申请)。
中断源向CPU提出的中断请求。CPU暂时中断原来的事务A,转去处理事件B。对事件B处理完毕后,再回到原来被中断的地方(即断点),称为中断返回。
实现上述中断功能的部件称为中断系统(如下图所示):
进入中断→保护现场→中断处理 → 恢复现场 →中断返回
中断方式优点:1、大大地提高了CPU的工作效率。
2、中断技术不仅解决了快速主机与慢速I/O设备的数据传送问题
3、分时操作。CPU可以分时为多个I/O设备服务,提高了计算机的利用率
4、实时响应。CPU能够及时处理应用系统的随机事件,系统的实时性大大增强;
5、可靠性高。CPU具有处理设备故障及掉电等突发性事件能力,从而使系统可靠性提高。
二、中断系统结构
中断系统结构见图。中断系统有5个中断请求源(简称中断源),2个中断优先级,可实现2级中断服务程序嵌套。每一中断源可用软件独立控制为允许中断或关闭中断状态;每一个中断源的优先级均可用软件设置。
2.1中断请求源
由图,中断系统共有5个中断请求源,它们是:
(1)INT0*—(P3.2)可由INT0(TCON.0)选择其为低电平有效还是下降沿有效。当CPU检测到P3.2引脚上出现有效的中断信号时,中断标志IE0(TCON.1)置1,向CPU申请中断。
(2)INT1*—(P3.3)可由INT1(TCON.2)选择其为低电平有效还是下降沿有效。当CPU检测到P3.3引脚上出现有效的中断信号时,中断标志IE1(TCON.3)置1,向CPU申请中断。
(3)TF0—(TCON.5),片内定时/计数器T0溢出中断请求标志。当定时/计数器T0发生溢出时,置位TF0,并向CPU申请中断。
(4)TF1—(TCON.7),片内定时/计数器T1溢出中断请求标志。当定时/计数器T1发生溢出时,置位TF1,并向CPU申请中断。
(5)RI(SCON.0)或TI(SCON.1),串行口中断请求标志。当串行口接收完一帧串行数据时置位RI或当串行口发送完一帧串行数据时置位TI,向CPU申请中断。
三、中断允许控制
CPU对中断系统所有中断以及某个中断源的开放和屏蔽是由中断允许寄存器IE控制的。
各中断源开放或屏蔽,是由片内中断允许寄存器IE控制。IE字节地址为A8H,可进行位寻址,格式见图。
四、中断请求标志
为定时器/计数器的控制寄存器,字节地址为88H,可位寻址。既包括定时器/计数器T0、T1溢出中断请求标志位TF0和TF1,也包括两个外部中断请求的标志位IE1与IE0,还包括两个外部中断请求源的中断触发方式选择位。TCON格式见图。
当IT0=0时,为电平触发方式。
当IT0=1时,为边沿触发方式(下降沿有效)。
五、响应优先级
同一优先级中的中断申请不止一个时,则有中断优先权排队问题。同一优先级的中断优先权排队,由中断系统硬件确定的自然优先级形成,其排列如所示:
51单片机的中断优先级原则:
1、CPU同时接收到几个中断时,首先响应优先级别最高的中断请求。
2、正在进行的中断过程不能被新的同级或低优先级的中断请求所中断。
为了实现上2、3两条原则,中断系统内部设有两个用户不能寻址的优先级状态触发器。其中一个置1,表示正在响应高优先级的中断,它将阻断后来所有的中断请求;另一个置1,表示正在响应低优先级中断,它将阻断后来所有的低优先级中断请求。
六、中断源
七、51单片机中断处理过程
中断响应条件:
以上三条同时满足时,CPU才有可能响应中断。
以外部中断0为例:
主程序中需要有以下代码:
EA=1;//打开总中断开关
EX0=1;//开外部中断0
IT0=0/1;//设置外部中断的触发方式
{
do anything that you want
}
八、例子代码
#include "reg52.h"
#include "intrins.h"
typedef unsigned char u8;
typedef unsigned int u32;
sbit LED=P0^0;
sbit KEY3=P3^2;
void delay(u32 i)//i==1 10us
{
while(i--);
}
/**
*Funtion:外部中断0中断处理函数(格式固定 interrupt 0(0为中断号))
*IN : void
*OUT : void
*
*/
void Int0() interrupt 0
{
delay(1000);//按键消抖
if(KEY3 == 0)
{
LED=~LED;
}
}
/**
*Funtion:外部中断0初始化函数
*IN : void
*OUT : void
*
*/
void Int0Init(void)
{
/* IE寄存器*/
EA = 1; //CPU中断允许(总允许)位
EX0 = 1; //外部中断0允许位
/* TCON寄存器*/
IT0 = 1; //外部中断0触发方式控制位
}
int main( void )
{
LED=0;
Int0Init();
while(1)
{
}
return 0;
}