前言
本文章原理部分较少,主要内容在于外部中断的应用已经程序的编写,如果想深究原理部分,可参考其他文章一、外部中断简要讲解分析
当CPU接收到中断请求后,若中断请求被允许,单片机会暂时中止当前正在执行的主程序,转到中断服务处理程序处理中断服务请求,处理完中断服务程序后,再回到原来被终止的主程序(断点)之处,继续执行主程序。
51单片机共有两个外部中断,外部中断0(INT0、中断号为0)和外部中断1(INT1、中断号为2)
外部中断由外部信号触发,在51单片机中,外部中断0由P3.2引脚触发,外部中断1由P3.3引脚触发
这里以外部中断0为例,图中当IT0 = 0时,外部中断0为上升沿和下降沿均可触发,当IT0 = 1时,外部中断0则只能下降沿触发。
由上图可知,**当IE0 = 1,EX0处开关闭合,无论PX0 = 0或PX0 = 1,若IT0 = 1,则只要P3.2引脚有下降沿出现,则外部中断0就会触发,**CPU就会暂停当前正在执行的程序,然后去执行外部中断0的中断函数。
在蓝桥杯单片机开发板上,按键S5接P3.2引脚,每当按键P3.2按下时,P3.2引脚瞬间变为低电平,则会在P3.2引脚产生一个下降沿。
二、程序逻辑分析
要想使用外部中断,则程序中必须要有外部中断的初始化函数以及外部中断对应的中断函数,
经过上面的分析,不难写出中断的初始化函数:
void Init_INT0()
{
IT0 = 1;
IE0 = 1;
EX0 = 1;
EA = 1; //开总中断
}
每个中断都要有中断服务函数,当CPU产生中断后,CPU会执行相应的中断服务函数
在51单片机中,我们在函数的声明后面加上’interrupt 中断号’则为中断号所对应中断的中断服务函数
则外部中断0的中断服务函数:
void INT0_work() interrupt 0 //外部中断0的中断号为0
{
}
以上配置完成后,当P3.2引脚有低电平的时(即按下按键S5),则CPU会执行INT0_work()函数
三、代码
//@mzw
//上电后,LED灯为自左向右的流水灯,按下按键S5后,LED8闪烁3次后继续流水灯的状态
#include <reg52.h>
#include <intrins.h>
sbit hc138_A=P2^5;
sbit hc138_B=P2^6;
sbit hc138_C=P2^7;
sbit LED_8 = P0^7;
/*****配置138译码器*****/
void HC138(unsigned int n)
{
switch(n)
{
case 4:
hc138_A=0 ; hc138_B=0 ; hc138_C=1; break;
case 5:
hc138_A=1 ; hc138_B=0 ; hc138_C=1; break;
case 6:
hc138_A=0 ; hc138_B=1 ; hc138_C=1; break;
case 7:
hc138_A=1 ; hc138_B=1 ; hc138_C=1; break;
}
}
/*****延时函数*****/
void delay(unsigned int k)
{
while(k--);
}
/*****外部中断0初始化函数*****/
void Init_INT0()
{
IT0 = 1;
IE0 = 1;
EX0 = 1;
EA = 1; //开总中断
}
/*****外部中断0中断服务函数*****/
void INT0_work() interrupt 0 //外部中断0的中断号为0
{
char i;
HC138(4);
P0 = 0xff;
for(i=1;i<=6;i++) //循环6次,3亮3灭
{
LED_8 = ~LED_8; //电平取反
delay(60000);
}
}
void main()
{
char x = 0xfe; //11111110
HC138(5);
P0=0x00; //蜂鸣器和继电器初始化、、全关
HC138(4);
P0= 0xff; //LED小灯初始化、、全关
Init_INT0(); //初始化外部中断0
while(1)
{
P0 = x;
x = _crol_(x,1); //循环左移
delay(60000);
}
}