目录
一、中断系统简介
中断系统是为使CPU具有对外界紧急事件的实时处理能力而设置的。
当中央处理机CPU正在处理某件事的时候外界发生了紧急事件请求,要求CPU暂停当前的工作,转而去处理这个紧急事件,处理完以后,再回到原来被中断的地方,继续原来的工作,这样的过程称为中断。实现这种功能的部件称为中断系统,请示CPU中断的请求源称为中断源。微型机的中断系统一般允许多个中断源,当几个中断源同时向CPU请求中断,要求为它服务的时候,这就存在CPU优先响应哪一个中断源请求的问题。通常根据中断源的轻重缓急排队,优先处理最紧急事件的中断请求源,即规定每一个中断源有一个优先级别。CPU总是先响应优先级别最高的中断请求。
当CPU正在处理一个中断源请求的时候(执行相应的中断服务程序),发生了另外一个优先级比它还高的中断源请求。如果CPU能够暂停对原来中断源的服务程序,转而去处理优先级更高的中断请求源,处理完以后,再回到原低级中断服务程序,这样的过程称为中断嵌套。这样的中断系统称为多级中断系统,没有中断嵌套功能的中断系统称为单级中断系统。
二、C51单片机的中断
这里就以STC89C52单片机的的中断系统为大家做一个详解,大家学习以后可以类比一下其他的中断系统,其实都是大同小异的。
1、外部中断
与c51单片机中断相关的寄存器有:
中断允许寄存器:IE
辅助中断控制寄存器:XICON
中断优先级控制寄存器高:IPH
中断优先级控制寄存器低:IP
定时器/计数器0/1 控制寄存器:TCON
串行口控制寄存器:SCON
定时器/计数器2控制寄存器:T2CON
但是我们进行外部中断时,一般只初始化IE 和TCON
说明:
EA:CPU的总中断允许控制位。EA = 1,CPU开放中断,EA = 0,CPU屏蔽所有的中断申请。EA的作用是使中断允许形成两级控制。即各中断源首先受EA控制;其次还受各中断源自己的中断允许控制位控制。
ET2:定时器/计数器2中断允许位。ET2 = 1,允许T2中断;ET2 = 0,禁止T2中断。
ES:串口中断允许位。ES = 1,允许串行口1中断;ES = 0,禁止串行口中断。ET1:定时/计数器T1的溢出中断允许位。ET1 = 1,允许T1中断;ET1 = 0,禁止T1中断。
EX1:外部中断1中断允许位。EX1 = 1,允许外部中断1中断;EX1 = 0,禁止外部中断1中断。
ET0:T0的溢出中断允许位。ET0 = 1,允许T0中断;ET0 = 0禁止T0中断。
EX0:外部中断0中断允许位。EX0 = 1,允许中断;EX0 = 0禁止中断。
TF1:T1溢出中断标志。T1被允许计数以后,从初值开始加1计数。当产生溢出时由硬件置1,向CPU请求中断,一直保持到CPU响应中断时,才由硬件清0。
TR1:定时器1的运行控制位。
TF0:T0溢出中断标志。T0被允许计数以后,从初值开始加1计数,当产生溢出时,由硬件置1,向CPU请求中断,一直保持CPU响应该中断时,才由硬件清0。
TR0:定时器0的运行控制位。
IE1:外部中断1请求源标志。IE1 = 1,外部中断向CPU请求中断,当CPU响应该中断时由硬件清0。
IT1:外部中断1中断源类型选择位。IT1 = 0,低电平信号可触发外部中断1。IT1 = 1,外部中断1为下降沿触发方式。
IE0:外部中断0请求源标志。IE0 = 1外部中断0向CPU请求中断,当CPU响应外部中断时,由硬件清0
IT0:外部中断0中断源类型选择位。IT0 = 0,低电平可触发外部中断0。IT0=1,外部中断0为下降沿触发方式。
我们了解了这两个寄存器后,再去看上面的中断原理图就能简单的了解一个外部中断的过程了。下面给大家附上一个外部中断0的例子,独立按键K3控制一个LED的亮灭。(程序为STC89C52RC单片机的,外部中断0接P3.2管脚,外部中断1接P3.3管脚)
#include"reg52.h"
//宏定义类型
typedef unsigned char u8;
typedef unsigned int u16;
//定义管脚
sbit KEY3 = P3^2;
sbit LED0 = P2^0;
//延时函数 如果传入数据为1,大概延时10us(晶振频率为11.0592mHZ)
void delay_10us(u16 ten_us)
{
while(ten_us--);
}
//外部中断0配置
void exti0_init()
{
IT0 = 1;//跳变沿触发方式(下降沿)
EX0 = 1;//打开INT0的中断允许
EA = 1;//打开总中断
}
//主函数
void main()
{
exti0_init();
while(1)
{
}
}
//外部中断0中断函数
void exit0() interrupt 0
{
delay_10us(1000);
if(KEY3==0)
{
LED0 = !LED0;
}
}
2、定时器/计数器中断
TCON在外部中断时已做介绍,我们可以看到TMOD这个工作方式寄存器,其高四位控制T1定时器中断,第四位控制T0定时器中断。
GATE:门控位。控制定时器是否受外部中断信号的影响;GATE = 0,同时TCON中的TR0 = 1时,定时器0可以开始工作。GATE = 1,除了TR0 = 1以外,还需要给外部中断0高电平(即INT0的管脚高电平),TR1同理。
C/:模式选择位。0:定时器模式。1:计数器模式
M1M0:工作方式选择位。如下图
一般都使用方式1和方式2。给大家详细讲一下方式1,大家就可以类比其他的工作方式了
当Tl0计数满溢出之后向TH0进位,当TH0计数满溢出时,TF0自动置1,向CPU发出中断申请。如上图。当GATE = 0(1处)时,到了非门(2处)变为1;然后经过或门(3处)(若是GATE = 1,则经过非门后就变为0,此时就要受到外部中断0(4处)的影响,即外部中断0的管脚置1,定时器才能正常工作),结果还是为1;此时就需要看TR0(5处),若中断程序允许定时器0工作,即TR0 =1,则经过与门(6处),导通开关(7处),开始定时。后面那个开关(8处)是选择工作模式为定时器还是计数器。
例子:定时器0中断方式1控制D1指示灯间隔1s闪烁
#include "reg52.h"
typedef unsigned int u16; //对系统默认数据类型进行重定义
typedef unsigned char u8;
//定义管脚
sbit LED1=P2^0;
void delay_10us(u16 ten_us)
{
while(ten_us--);
}
void time0_init(void)
{
TMOD|=0X01;//选择为定时器0模式,工作方式1
TH0=0XFC; //给定时器赋初值,定时1ms
TL0=0X18;
ET0=1;//打开定时器0中断允许
EA=1;//打开总中断
TR0=1;//打开定时器
}
void main()
{
time0_init();//定时器0中断配置
while(1)
{
}
}
void time0() interrupt 1 //定时器0中断函数
{
static u16 i;//定义静态变量i
TH0=0XFC; //给定时器赋初值,定时1ms
TL0=0X18;
i++;
if(i==1000)//循环1000次,即1s
{
i=0;
LED1=!LED1;
}
}
三、总结
中断这一部分就主要是对寄存器的操作,重点也是各个寄存器。我们看懂了所使用的开发板的中断系统原理图,再结合相应的寄存器,其实实现中断也不是一个难题。但是对于寄存器初学的朋友可能记忆有些困难,但是使用多了就熟练了,所以自己可以尝试一下其他的中断来加深自己的理解。