单片机之于中断,十分重要,举个例子,没有了中断,单片机需要不断查询设备的状态,有了中断之后,中断源向单片机要求中断服务时,单片机才会停下来处理,就显得十分高效有序。 针对中断,我们怎么学呢 , 其实呀,很简单,只需要理解一张图
对的,没错就是这张中断系统结构图。下面我们就说说 ,从这张图上,我们能读出来些什么:
①:51单片机 有 5个中断源: 外部中断0(
)(12引脚),外部中断1(
)(13引脚,详见下图),Timer0 中断(TF0), Timer 1中断 (TF1), 串行通信中断(R1/T1);
中断源 | 向量地址 | 中断标志位 |
外部中断0(INT0) | 0003H | IE0 |
Timer 0中断(TF0) | 000BH | TF0 |
外部中断1(INT1) | 0013H | IE1 |
Timer 1中断(TF1) | 001BH | TF1 |
串行通信中断(R1/T1) | 0023H | T1/R1 |
②:对于外部中断,使单片机产生外部中断的信号有两种形式,一种是低电平触发,一种是下降沿触发;从上图中,我们我们可以看到,在 IT0 和 IT1置0时,为低电平触发 ;置1时,即为下降沿触发;
低电平触发:
低电平触发模式是单片机默认的外部中断方式,当单片机上电复位后,使能外部中断时,就默认以低电平方式触发,这种低电平触发外部中断的方式又称为电平触发方式 。
在低电平触发模式下,外部中断信号输入端
和
出现低电平就会触发外部中断0或外部中断1.外部中断产生时,单片机会立即停止正在执行的指令,并根据中断向量表中的中断向量转入相应的地址执行外部中断服务子程序。
在单片机进入中断服务子程序执行并在中断结束指令“RET1”之前,这个低电平必须撤走,否则将会使单片机执行完指令“RET1”后因INT0 或 INT1 仍为低电平而再次进入中断服务子程序。
下降沿触发:
边沿触发也是一种常用的触发外部中断的模式。在该模式下,INT0端或INT1端出现下降沿即可使单片机产生中断。
下面我们来说说TCON中与中断相关的控制位:
TF1(位1) | TR1(位6) | TF0(位5) | TR0(位4) | IE1(位3) | IT1(位2) | IE0(位1) | IT0(位0) |
红色是Timer 1 .橙色是 Timer 0,这里我们先不提。其余四位便是与中断有关的控制位。
位数 | 位标记 | 描述 |
3 | IE1 | 外部中断1 下降沿标志位 当下降沿触发的外部中断1 时,硬件将该位清0 INT1端 (13管脚),接收到外部中断信号时,由硬件置1 |
2 | IT1 | 外部中断1 方式控制位 清0时为INT1端选择低电平触发方式 置1时为INT1端选择下降沿触发方式 |
1 | IE0 | 外部中断0边沿标志位 当下降沿触发的外部中断0时, 硬件将该位清0 INT0端(12管脚)接收到外部中断信号时,由硬件置1 |
0 | IT0 | 外部中断0方式控制位 清0时为INT0端选择低电平触发方式 置1时为INT0端选择下降沿触发方式 |
③:图片由左向右,接下来要说的是中断使能寄存器IE,附上表如下:
EA(位7) | 保留 | 保留 | ES(位4) | ET1(位3) | EX1(位2) | ET0(位1) | EX0(位0) |
位数 | 位标记 | 描述 |
7 | EA | 中断使能位 清0时屏蔽所有中断,置1时开放所有中断 开放所有中断后,各个中断由以下各自的控制位控制使能或屏蔽 |
6 | 保留 | 不要访问该位,也不要往该位写数据 |
5 | ||
4 | ES | 串行口中断使能位 清0时屏蔽串行口中断,置1时使能串行口中断 |
3 | ET1 | Timer 1中断使能位 清0时屏蔽Timer 1中断,置1时使能Timer 1中断
|
2 | EX1 | 外部中断1使能位 清0时屏蔽外部中断1,置1时使能外部中断1 |
1 | ET0 | Timer 0中断使能位 清0时屏蔽Timer 0中断,置1时使能Timer 0中断 |
0 | EX0 | 外部中断0使能位 清0时屏蔽外部中断0,置1时使能外部中断0 |
这里,特别要提醒的就是:EA,如果EA=1时,相应的中断由IE中相应的位来控制,控制位置1使能中断;清0则屏蔽中断,这一天从图中看的很清楚。
④:接着要说的就是,中断优先级寄存器IP了。还是附上表:
优先级 | 中断源 |
从高到底 | 外部中断0 INT0 |
Timer 0中断 TF0 | |
外部中断1 INT1 | |
Timer 1中断 TF1 | |
串行通信中断 R1/T1 |
例如,Timer 0 中断和外部中断1 如果同时产生,单片机会先去响应Timer 0中断并处理它的中断服务子程序。完成后再响应外部中断1,进入相应的中断服务子程序。
保留 | 保留 | 保留 | PS(位4) | PT1(位3) | PX1(位2) | PT0(位1) | PX0(位0) |
位数 | 位标记 | 描述 |
7 | 保留 | 不要访问该位 , 也不要往该位读写数据 |
6 | ||
5 | ||
4 | PS | 串行通信中断优先控制位 置1时优先响应串行通信中断 |
3 | PT1 | Timer 1 中断优先控制位 置1时优先响应Timer 1中断 |
2 | PX1 | 外部中断 1中断优先控制位 置1时优先响应外部中断1 |
1 | PT0 | Timer 0 中断优先控制位 置1时优先响应Timer 0中断 |
0 | PX0 | 外部中断0中断优先控制位 置1时优先响应外部中断0 |
从结构图中,我们可以清楚地看出来这种优先关系。
最后:我们来说一下,如何用C51来编写中断函数:
中断函数格式如下:
void 函数名()interrupt 中断号 using 工作组
{
中断服务程序内容
}
例如下面代码用 C51 编写定时器 0 中断处理函数。
#include<reg52.h>
unsigned int interruptcnt;
unsigned char second;
void timer0 (void) interrupt 1 using 2 {
if(++interruptcnt == 4000) { // count to 4000
second++; // second counter
interruptcnt = 0; // clear int counter
}
}