中断是为单片机实时处理外部和内部随机机事情而设置的一项基本功能,中断功能的存在,极大的提高了单片机处理外部和内部事件的能力,目前几乎所有单片机都会配置的这一项基本功能,而中断功能的强弱也成为衡量一种单片机功能是否强大的重要指标之一。作为单片机的学习者,中断的概念及编程能力必须要灵活的掌握并学会应用。
单片机中断功能的强弱因单片机的种类不同而不同,51单片机的中断功能相对简单,内部有5个中断源,像一些高级的单片如飞思卡尔有上百个中断源。但知识都是相通的,51单片机中断的概念弄懂白了,其它单片机的也就是一个了解和熟悉的过程。
51单片机内部总共有5个中断源,分别外部中断0、定时器中断0、外部中断0、定时器中断1、串行中断。后面的章节我们分别的进行介绍,这一课我们以主要外部中断0进行介绍。
这里我们先介绍一些基本的概念、
一、中断的概念
我们先来举日常生活中的一个例子,如图1所示,你正在专心看书,突然电话铃响,于是你记下正在看的书的页数,去接电话,接完电话后再回来接着看书。这实际就是中断的一个例子。
在单片机中,CPU在处理某一事件A时,发生了另一事件B(中断发生);CPU暂时中断当前的工作,转去处理事件B(中断响应和中断服务);处理完毕后,再回到原来事件A被中断的地方继续处理事件A(中断返回),这一过程称为中断,如图2。
图1 日常生活中中断例子 图2 单片机中中断例子
下面有几个中断的概念需要记住:
中断源:将能引起中断的事件称为中断源,如电话铃响,51单片机共有5个中断源,分别为外部中断0、定时器中断0、外部中断1、定时器中断1、串口中断。
断点:中断发生的地方称为断点。
主程序:CPU现行运行的程序称为主程序,如看书。
中断服务子程序:处理随机事件的程序称为中断服务子程序,如接电话。
中断系统:实现中断功能的部件称为中断系统。
二、MCS-51的中断系统
51单片机中断系统的结构图如图3所求,总共有51个中断源,分别如下。
图3 51单片机中断系统结构图
(1)INT0-外部中断0,由P3.2端口引入,可设置为低电平触发或下降沿触发。
(2)INT1-外部中断1,由P3.3端口引入,可设置为低电平触发或下降沿触发。
(3)T0-定时器/计数器中断0,由内部计数器计满溢出触发。
(4)T1-定时器/计数器中断1,由内部计数器计满溢出触发。
(5)TI/RI-串行口中断,由串行口完成一帧字符发送/接受后触发。
中断系统是单片机内部一个种要的功能模块,从程序开发的角度讲,对单片机内部功能模块结构上不需要掌握得太深,因为要让各功能模块发挥其强大的功能,只需要正确设置相应寄存器就可以了,所以这里我们中断的具体结构这里我不过多分析,下面介绍相关的寄存器。
三、51单片机相关寄存器
51单片机内部共有21个特殊功能寄存器, 编程时如用C语言编程中我们只需要撑握IP、IE、SCON、TCON、P1、P2、P3、P4、PCON TMOD、TL0、TH0、TL1、TH1、SBUF15个寄存器,如图4所示,已用红线和蓝线标出,注意红线的能进行位操作,蓝线的不能进行位操作。
图4 51单片机特殊功能寄存器[page]
这15寄存器中,根据前面讲的51单片机内部四大功能模块又可分为四大部分:
I/O口相关:P1、P2、 P3、 P4
中断相关:IP、 IE
定时器相关:TMOD、 TCON、 TL0、TH0、TL1、TH1
串口通信相关:SCON、 PCON、 SBUF
需要注意的是,在这四大部分中,除I/O口操作相关的P1、P2、P3、P4相对独立外,其它11个寄存器使用时通常会相互结合使用,也就是说中断、定时器和串口通信三者通常会结合起来用,如外部中断时,设置边沿触发还是电平触发需设置TCON寄存器中的TR0和TR1位,使用定时器时又可能用到中断,而串口通信时设置波特率又直接跟定时器相关。
这节里因为我们主要介绍外部中断0,所以跟外部中断相关的寄存器就只有IE、IP、TCON三个,而对于初学都来说,IP寄存器(中断优先寄存器)一般用不到,所里这里只介绍IE(中断允许寄存器)和TCON(定时器控制寄存器)。
(1)IE中断允许寄存器
EA:EA=0时,所有中断禁止(即不产生中断);EA=1时,各中断的产生由个别的允许位决定
ET2:定时2溢出中断允许(8052用1允许, 0禁止)
ES:串行口中断允许(1允许, 0禁止)
ET1):定时1中断允许(1允许, 0禁止)
EX1:外中断INT1中断允许(1允许, 0禁止)
ET0:定时器0中断允许(1允许, 0禁止)
EX0:外部中断INT0的中断允许(1允许, 0禁止)
(2)TCON定时器控制寄存器
TF1:定时器T1溢出标志,可由程序查询和清零,TF1也是中断请求源,当CPU响应T1中断时由硬件清零。
TF0:定时器T0溢出标志,可由程序查询和清零,TF0也是中断请求源,当CPU响应T0中断时由硬件清零。
TR1:T1充许计数控制位,为1时充许T1计数(定时)。
TR0:T0充许计数控制位,为1时充许T0计数(定时)。
IE1:外部中断1请示源(INT1,P3.3)标志。IE1=1,外部中断1正在向CPU请求中断,当CPU响应该中断时由硬件清“0”IE1(边沿触发方式)。
IT1:外部中断源1触发方式控制位。IT1=0,外部中断1程控为电平触发方式,当INT1(P3.3)输入低电平时,置位IE1。此位为1设置为电平触发,为0设置为下降沿触发。
IE0:外部中断0请示源(INT0,P3.2)标志。IE0=1,外部中断1正在向CPU请求中断,当CPU响应该中断时由硬件清“0”IE0(边沿触发方式)。
IT0:外部中断源0触发方式控制位。IT0=0,外部中断1程控为电平触发方式,当INT0(P3.2)输入低电平时,置位IE0。此位为1设置为电平触发,为0设置为下降沿触发。
四、外部中断程序举例
明白了寄存器后,下面我以外部中断0为例写一个程序,程序的功能为:在主程序里L1灯常亮,当外部脚P32检测到有下降沿时,L1灯熄灭。
我们先来分析下该程序的书写思路。首先在主程序里我们应该让L1灯常亮;然后需要对中断相关的寄存器进行设置,主要为打开总中断、打开外部中断0,并且还需要设置外部中断为低电平触发方式;最后我们要写一个中断子函数。
相应的程序如例一所示。
例一 外部中断0程序
#include
#define uint unsigned int
#define uchar unsigned char
sbit D1=P1^0;
void delay(uint z);
void main()
{
IT0=0;//设置为0低电平触发
Eaa=1;//开总中断
EX0=1;//开外部中断0
while(1)
{
D1=1;
}
}
void exter0() interrupt 0
{
D1=0;
delay(500);//下降沿触发时如果不延时观察不到再现象
}
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
下载到实验板现象如图5所示。
这里要注意的中断子函数的写法。51单片机中中断子函数的格式如下:
void 函数名()interrupt 中断号
{
中断服务子程序的内容
}
中断函数不能返回任何值,所以前面用void;后面紧跟函数名,名字可以随便取,但不要与C语言中的关键字相同;中断函数不带任何参数,所以函数名后面的小括号内为空;中断号是指单片机中几个中断源的序号,每个中断源的中断序号如图6所示。这个中断号是编译器识别不同中断的的唯一,必须书写正确,否者单片机进不了中断子程序
图6 52单片机的中断号