1,引入
cpu收到中断请求,将main函数中的事情停下来,转而执行中断处理函数中的事情,我使用的51单片机有5个中断源,2个外部中断(INT0/INT1),2个定时器中断(T0/T1)和一个串口中断。
那系统是如何区分这些中断的啦,即每个中断有一个中断号,同时中断有优先级,可以通过软件控制,高优先级的中断可以抢占低优先级的中断,当两个相同优先级的中断到来,cpu会根据系统中的中断查询顺序,当中断来临时,只有中断号正确才能进入中断,并依次序来处理中断。
2,51单片机中断
我使用的单片机有5个中断,如下:
IE寄存器:中断控制寄存器,EA叫总中断,EX0,ET0, EX1,ET1,ES等为其他5个中断的使能寄存器。 IP寄存器为中断优先级控制
INT0、INT1外部中断:
1, 与该中断连接的管脚是P3.2,同时在一个原理图上搜索,P32管脚连接着独立按键K3,也发现独立按键K4,连接着P33,即连接着外部中断INT1.
2,从图中可以看到IT0,这个寄存器控制着中断触发方式,INT0 = 1时,为下降沿触发,INT0 = 0时,为低电平触发方式(非门)
3,当 CPU 检测到 P3.2 引脚上出现有效的中断信号时,中断标 志 IE0(TCON.1)置 1,向 CPU 申请中断
3,中断相关的寄存器
1,开启对应中断,需要对应寄存器设置为1,并开启总中断,
如外部中断INT0 => EX0= 1,EA = 1 (同时需要设置触发方式:IT0 = 1,下降沿触发,详见下图)
4,外部中断INT0程序
程序实现点击 => KEY3,KEY4 实现LED1 或 LED2的亮灭。
#include <reg52.h>
typedef unsigned char u8;
typedef unsigned int u16;
sbit LED1 = P2^0;
sbit LED2 = P2^1;
sbit KEY3 = P3^2;
sbit KEY4 = P3^3;
#define DC_RUNING_TIME 1000
void delay_10us(u16 time)
{
while(time--);
}
void delay_ms(ms)
{
u16 i,j;
for(i=ms;i>0;i++)
for(j=110;j>0;j--);
}
void init_exti0()
{
// 初始化外部中断0
IT0 = 1; // 下降沿触发
EX0 = 1;
EA = 1;
}
void init_exti1()
{
// 初始化外部中断0
IT1 = 1; // 下降沿触发使能
EX1 = 1; // 启用外部中断1
EA = 1; // 开启中断
}
//interrupt 是一个关键字,表示 51 单片机中断。后面的“0”是中断号
void exti0_run() interrupt 0
{
delay_10us(DC_RUNING_TIME);
if(KEY3 == 0)
{
LED1 = !LED1;
}
}
void exti1_run() interrupt 2
{
delay_10us(DC_RUNING_TIME);
if(KEY4 == 0)
{
LED2 = !LED2;
}
}
void main()
{
init_exti0();
init_exti1();
while(1);
}
5,总结
cpu要正常相应中断需要三个条件:
①中断源有中断请求
②此中断源的中断允许位为 1
③CPU 打开了总中断(即 EA=1)
下一篇将介绍定时器中断。。。