51单片机的中断系统
开发板:普中51-单核-A2;
仿真软件:proteus;
开发环境:Keil4;
参考资料:开发板所附视频;
如有错误,感谢指正。如有侵权请联系博主。
中断的概念
- CPU在处理某一个事件A时,发生了应一个事件B请求CPU迅速去处理(中断发生);
- CPU暂时中断当前的工作,转去处理事件B(中断响应和中断服务);
- 待CPU将事件B处理完毕后,再回到原来事件A被中断的地方继续处理事件A(中断返回);
以上这一过程称为中断。
引起CPU中断的根源称为中断源。中断源向CPU提出中断请求,CPU暂时中断原来的事件A,转去处理事件B,对事件B处理完毕后,再回到原来被中断的地方(即断点),称为中断返回。实现中断功能的部件称为中断系统。
中断技术的优点
解决快速主机与慢速I/O设备的数据传送问题,还具有如下优点:
- 分时操作,CPU可以分时为多个I/O设备服务,提高了计算机的利用率;
- 实时响应,CPU能够及时处理应用系统的随机事件,系统的实时性大大增强;
- 可靠性高,CPU具有处理设备故障及掉电等突发性事件能力,从而使系统可靠性提高;
51单片机的中断系统结构
89c51/52
的中断系统有5个中断源,2个优先级,可以实现二级中断嵌套。
5个中断源分别是:外部中断0(IT0
)、定时/计数器T0
(TF0
)、外部中断1(IT1
)、定时/计数器T1
(TF1
)、串行口中断RI/TI。
- 外部中断0(
IT0
)(引脚P3.2
),可由IT0
(TCON.0
)选择为低电平触发还是下降沿触发。当CPU检测到P3.2
引脚上出现有效的中断信号时,中断请求标志IE0
(TCON.1
)置1,表示向CPU申请中断。 - 外部中断1(
IT1
),由IT1
(TCON.2
)选择其为低电平有效还是下降沿有效。当CPU检测到P3.3
引脚上出现有效的中断信号时,中断请求标志IE1
(TCON.3
)置1,表示向CPU申请中断。 - 定时/计数器
T0
(TF0
),片内定时/计数器T0溢出中断请求标志。当定时/计数器T0发生溢出时,中断请求标志位TF0
(TCON.5
)置为1,表示向CPU申请中断。 - 定时/计数器
T1
(TF1
),片内定时/计数器T1溢出中断请求标志。当定时/计数器T1发生溢出时,中断请求标志位TF1
(TCON.7
)置为1,表示向CPU申请中断。 - 串行口中断RI(
SCON.0
)/TI(SCON.1),当串行口接收完一帧串行数据时,SCON.0
置为1,或 当串行口发送完一帧串行数据时,SCON.1
置为1,向CPU申请中断。
中断允许控制-IE
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中断允许位,总允许位;
中断请求标志-TCON
ITO(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溢出中断请求标志位;
中断优先级:
中断源 | 中断标志 | 终端服务程序入口 | 优先级顺序 |
---|---|---|---|
外部中断0( I N T 0 ‾ \overline{INT0} INT0) | IE0 | 0003H | 高 |
定时/计数器0(T0) | TF0 | 000BH | ⬇ |
外部中断1( I N T 1 ‾ \overline{INT1} INT1) | IE1 | 0013H | ⬇ |
定时/计数器1(T1) | TF1 | 001BH | ⬇ |
串行口 | RI或TI | 0023H | 低 |
中断源:
中断源符号 | 名称 | 中断引起原因 | 中断号 |
---|---|---|---|
/INT0 | 外部中断0 | P3.2引脚低电平或下降沿信号 | 0 |
T0 | 定时器0中断 | 定时器/计数器0计数回0溢出 | 1 |
/INT1 | 外部中断1 | P3.3引脚低电平或下降沿信号 | 2 |
T1 | 定时器1中断 | 定时/计数器1计数回0溢出 | 3 |
TI/RI | 串行口中断 | 串行通信完成一帧数据发送或接收引起中断 | 4 |
中断优先级原则
- CPU同时接收到几个中断时,首先响应优先级别最高的中断请求;
- 正在进行的中断过程不能被新的同级或低优先级的中断请求所中断;
- 正在进行的低优先级中断服务,能被高优先级中断请求所中断;
为了实现后面两条原则,中断系统内部设有两个用户不能寻址的优先级状态触发器。其中一个置1表示正在响应高优先级的中断,它将阻断后来所有的中断请求;另一个置1,表示正在响应低优先级中断,它将阻断后来所有的低优先级中断请求。
中断处理过程
中断响应条件:
- 中断源有中断请求;
- 此中断源的中断允许位为1;
- CPU开中断即EA=1;
同时满足上面三个条件,CPU才有可能响应中断。
以外部中断0为例,使用中断时需要以下流程:
EA=1; // 打开总中断开关 即CPU开中断
EX0=1; // 开外部中断0,EX0为外部中断0允许位
IT0=0/1; // 设置外部中断的触发方式 ,0=电平触发,1=边缘触发
// 中断服务函数
void int0() interrupt 0 using 1 // 0是中断号
{
// 中断服务处理函数
}
中断示例,实现的功能:
-
程序开始在数码管显示0~7的数字;
-
独立按键K3/K4连接外部中断0P3.2和外部中断1P3.3,使用这两个按键控制P2.0连接的LED的亮灭,并使数码管不显示数字;
proteus仿真原理图:
实现代码:
#include "reg52.h"
#include "intrins.h"
typedef unsigned int u16;
typedef unsigned char u8;
// 通过按键控制led,在中断处理函数中改变led状态
sbit K3 = P3^2;
sbit K4 = P3^3;
sbit LED = P2^0;
// 数码管段选
u8 code segment[] = {0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39,0x5e,0x79,0x71};
sbit LSA = P2^2;
sbit LSB = P2^3;
sbit LSC = P2^4;
void delay(unsigned int i)
{
while(i--);
}
// 外部中断0触发函数
void Int0Init()
{
IT0 = 1; // 设置中断触发方式为边缘触发
EX0=1; // 外部中断允许位
EA=1; // 总中断打开
}
// 外部中断1触发函数
void Int1Init()
{
IT1 = 1; // 设置中断触发方式为边缘触发
EX1=1; // 外部中断允许位
EA=1; // 总中断打开
}
void show_LCD()
{
u8 i=0;
for(i=0;i<8;i++)
{
switch(i)
{
case 0:
LSA=0;LSB=0;LSC=0;break;
case 1:
LSA=1;LSB=0;LSC=0;break;
case 2:
LSA=0;LSB=1;LSC=0;break;
case 3:
LSA=1;LSB=1;LSC=0;break;
case 4:
LSA=0;LSB=0;LSC=1;break;
case 5:
LSA=1;LSB=0;LSC=1;break;
case 6:
LSA=0;LSB=1;LSC=1;break;
case 7:
LSA=1;LSB=1;LSC=1;break;
}
P0 = segment[i];
delay(50000); // 此处为了显示效果,所以加了很长时间的延时
P0=0;
}
}
void main()
{
Int0Init(); // 初始化中断响应条件
Int1Init();
while(1)
{
show_LCD();
}
}
void Int0() interrupt 0
{
delay(1000);
if(K3 == 0) // 按键按下变为低电平
{
LED = ~LED;
P0=0;
delay(50000); // 此处为了显示效果,所以加了很长时间的延时
}
}
void Int1() interrupt 2
{
delay(1000);
if(K4 == 0) // 按键按下变为低电平
{
LED = ~LED;
P0=0;
delay(50000); // 此处为了显示效果,所以加了很长时间的延时
}
}
演示结果,可以看到当有中断产生(K3或K4被按下)后,会去执行中断程序,中断执行结束,再回到原来的位置执行。