对于单片机来讲,中断是指 CPU 在处理某一事件 A 时,发生了另一事件 B, 请求CPU迅速去处理(
中断发生
);CPU暂时停止当前的工作(
中断响应
), 转去处理事件 B(
中断服务
);待CPU将事件B处理完毕后,再回到原来事件 A 被中断的地方继续处理事件 A(
中断返回
),这一过程称为
中断
。
引起 CPU 中断的根源称为
中断源
。中断源向 CPU 提出中断请求,CPU 暂时中断原来的事务 A,转去处理事件 B,对事件 B 处理完毕后,再回到原来被中断的地方(即
断点
),称为中断返回。实现上述中断功能的部件称为中断系统(
中断机构
)。
STC89C5X 系列单片机提供了 8 个中断请求源,它们分别是:
外部中断 0(INT0)、外部中断 1(INT1)、外部中断 2(INT2)、外部中断 3(INT3)、定时器 0 中断、定时器 1 中断、定时器 2 中断、串口(UART)中断。
但注意:51 系列单片机一定有基本的5个中断,但不全有8个中断,需要查看芯片手册,通常使用的都是基本的5个中断:INT0、INT1、定时器 0/1,串口中断。
高优先级的中断请求可以打断低优先级的中断,反之,低优先级的中断请求不可以打断高优 先级及同优先级的中断。当两个相同优先级的中断同时产生时,将由查询次序来决定系统先响应哪个中断。
STC89C5X 系列单片机的各个中断查询次序表
通过设置新增加的特殊功能寄存器 IPH 中的相应位,可将中断优先级设为四级,如果只设置 IP 或 XICON,那么中断优先级就只有两级,与传统 8051 单 片机两级中断优先级完全兼容。上图中的中断查询次序即为
中断号
,这个中断号在编程时非常重要,当中断来临时,只有中断号正确才能进入中断。
51 单片机一定有的 5 个中断
①INT0 对应的是 P3.2 口的附加功能,可由 IT0(TCON.0)选择其为
低电平有效
还是
下降沿有效
。当 CPU 检测到 P3.2 引脚上出现有效的中断信号时,中断标志 IE0(TCON.1)置 1,向 CPU 申请中断。
②INT1 对应的是 P3.3 口的附加功能,可由 IT1(TCON.2)选择其为
低电平有效
还是
下降沿有效
。当 CPU 检测到 P3.3 引脚上出现有效的中断信号时,中断标志 IE1(TCON.3)置 1,向 CPU 申请中断。
③T0 对应的是 P3.4 口的附加功能,TF0(TCON.5),片内定时/计数器 T0 溢出中断请求标志。当定时/计数器 T0 发生溢出时,置位 TF0,并向 CPU 申请中断。
④T1 对应的是 P3.5 口的附加功能,TF1(TCON.7),片内定时/计数器 T1 溢出中断请求标志。当定时/计数器 T1 发生溢出时,置位 TF1,并向 CPU 申请中断。
⑤RXD 和 TXD 对应对应的是 P3.0 和 P3.1 口的附加功能,RI(SCON.0)或 TI (SCON.1),串行口中断请求标志。当串行口接收完一帧串行数据时置位 RI 或 当串行口发送完一帧串行数据时置位 TI,向 CPU 申请中断
(1)中断允许控制
CPU 对中断系统所有中断以及某个中断源的开放和屏蔽是由
中断允许寄存器IE
控制的。
EX0(IE.0),外部中断 0 允许位;
ET0(IE.1),定时/计数器 T0 中断允许位;
EX1(IE.2),外部中断 0 允许位;
ET1(IE.3),定时/计数器 T1 中断允许位;
ES(IE.4),串行口中断允许位;
EA (IE.7), CPU 中断允许(总允许)位。
(2)中断请求标志 TCON
IT0(TCON.0),外部中断 0
触发方式控制位
。
当 IT0=0 时,为电平触发方式。 当 IT0=1 时,为边沿触发方式(下降沿有效)。
IE0(TCON.1),外部中断 0
中断请求标志位
。
IT1(TCON.2),外部中断 1 触发方式控制位。
IE1(TCON.3),外部中断 1 中断请求标志位。
TF0(TCON.5),定时/计数器 T0 溢出中断请求标志位。
TF1(TCON.7),定时/计数器 T1 溢出中断请求标志位。
(3)中断优先级
同一优先级中的中断申请不止一个时,则有中断优先权排队问题。同一优先级的中断优先权排队,由中断系统硬件确定的自然优先级形成,其排列如所示:
(4)中断号
(5)中断响应条件
①中断源有中断请求;
②此中断源的中断允许位为 1;
③CPU 开中断(即 EA=1)
例如:外部中断 0
EA=1;//打开总中断开关
EX0=1;//开外部中断 0
IT0=0/1;//设置外部中断的触发方式
中断服务函数:
void int0() interrupt 0 using 1
{
//编写用户所需的功能代码
}
在中断函数中 int0 是函数名,可自定义,但必须符合 C 语言标识符定义规则,interrupt 是一个关键字,表示 51 单片机中断。后面的“0”是中断号,外部中断 0 中断号为 0,这个可参考前面的内容。后面的 using 1 可省略不写。
下面用代码做例子:
代码实现内容为:main里面的主函数控制led流水灯,外部中断0控制第一个八段数码管从1变到F,外部中断1控制最后一个八段数码管从1变到F。
#include"reg52.h"
#include<intrins.h>
typedef unsigned int u16;
typedef unsigned char u8;
sbit k3=P3^2;//k3、k4是独立按键
sbit k4=P3^3;
sbit LSA=P2^2;//详细看静态数码管章节,本案例需要把J24模块的OE接VCC
sbit LSB=P2^3;
sbit LSC=P2^4;
void delay(u16 s);
void int0init();
void int1init();
u16 number=0xfe;
u8 num[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //控制八段数码管显示1~F
void main()
{
int0init();//开外部中断0
int1init();//开外部中断1
while(1) //控制流水灯
{
P2=number;
number=_crol_(number,1);
delay(10000000);
}
}
void delay(u16 s)
{
while(s--);
}
void int0init() //开外部中断0
{
IT0=1;
EX0=1;
EA=1;
}
void int1init() //开外部中断1
{
IT1=1;
EX1=1;
EA=1;
}
//下面代码可参考静态数码管部分
void Int0() interrupt 0 //外部中断0发生后需要CPU完成什么工作
{
delay(1000);
if(k3==0) //消抖
{
unsigned int i,j;
LSA=1;
LSB=1;
LSC=1; // CBA 111 表示最高位的数码管输出
for(i=0;i<=15;i++) //在LED对应的8段数码管循环显示0~F
{
P0=num[i];
j=100000000;
while(j--); //延时一段时间
}
}
}
void Int1() interrupt 2
{
delay(1000);
if(k4==0)
{
unsigned int i,j;
LSA=0;
LSB=0;
LSC=0; // CBA 000 表示最低位的数码管输出
for(i=0;i<=15;i++) //在LED对应的8段数码管循环显示0~F
{
P0=num[i];
j=100000000;
while(j--); //延时一段时间
}
}
}