参考文献:【新提醒】【蓝桥杯单片机07】彻底理解51单片机的中断系统 - - 21ic电子技术开发论坛
中断定义:
你正在追电视剧《神雕侠侣》,正看得入迷的时候,电话响了,你暂停电视剧,去接电话,在接电话的过程中,门铃又响了,你暂时放下电话,去把门打开。如果追电视剧是在执行主程序,那么电话就是中断源,电话铃响了就是中断请求,暂停电视就是现场保护,接电话就是中断响应,门铃响了是更高一级的中断请求,去把门打开,那就是中断嵌套。开完门回来接着聊电话,那是中断返回,接完电话把电视剧暂停打开就是现场恢复。
内核与外设之间的主要交互方式有两种:轮询和中断。轮询的方式貌似公平,但实际工作效率很低,且不能及时响应紧急事件;中断系统使得内核具备了应对突发事件的能力。
中断有个特点,就是你不知道中断什么时候发生。因此,每个中断都需要有一个中断入口地址,也成为中断向量。这样,不管中断在什么时候发生,它都有一个确定的程序执行起始点。中断响应之后,执行的那段程序,我们称作中断服务函数,也就是这个函数专门是为该中断服务的。
中断相关寄存器:
中断相关的寄存器有4个,每个寄存器都是可以位寻址的,这该编程带来了方便。 其中2个为控制寄存器:IE寄存器与IP寄存器:
另外2个为中断请求标志:TCON寄存器与SCON寄存器:
一般情况下,中断的处理函数有两个,其一为中断初始化函数,其二为中断服务函数。初始化函数就是一个普通的函数,而中断服务函数却有特殊的格式要求:
<1> 中断函数没有返回值,也不能带参数。
<2> 函数名后面要跟一个关键字interrupt,说明这是一个中断服务函数。
<3> 在关键字interrupt后面要跟上中断号,说明这个中断服务函数是为那个中断服务的。
中断服务函数的格式为:
void 函数名() interrupt 中断号
{ ----函数体---- }
我们要利用定时器0来进行间隔定时,中断程序架构我们C语言可以这样写:
题目:
电路图:
蓝桥杯单片机仿真原理图:蓝桥杯单片机仿真原理图.pdsprj-讲义文档类资源-CSDN文库
代码:
#include<reg52.h>
//译码器定义
sbit HC138_C =P2^7;
sbit HC138_B =P2^6;
sbit HC138_A =P2^5;
//LED定义
sbit L1 =P0^0;
sbit L8 =P0^7;
//只用到了控制LED(Y4)的锁存器
void SwitchHC138(unsigned char channel)
{
switch(channel)
{
case 4:
HC138_C= 1;
HC138_B= 0;
HC138_A= 0;
break;
case 5:
HC138_C= 1;
HC138_B= 0;
HC138_A= 1;
break;
}
}
void DelayL(unsigned int t)
{
while(t--);
while(t--);
}
//L1闪烁函数
void Working()
{
SwitchHC138(4);
L1 = 0; //点亮
DelayL(60000);
DelayL(60000);
L1 =1; //熄灭
DelayL(60000);
DelayL(60000);
}
// ==========================
//中断初始化
void Init_INT0()
{
IT0 = 1;
EX0=1;
EA=1;
}
//中断服务函数(方法一:在按下按键L8点亮,同时L1也会出现点亮的情况)
//void Service1_INT0() interrupt 0
//{
// L8 = 0;
// DelayL(60000);
// DelayL(60000);
// L8 = 1;
// DelayL(60000);
// DelayL(60000);
//
//}
// ==========================
//中断服务函数(方法二:使用标志量进行点亮L8,该方法是在Working函数执行完成后在执行Light函数)
unsigned char flag =0;
void Service2_INT0() interrupt 0
{
flag = 1;
}
void Light()
{
if(flag == 1)
{
L8 = 0;
DelayL(60000);
DelayL(60000);
L8 = 1;
DelayL(60000);
DelayL(60000);
}
flag =0;
}
// ==========================
void Init()
{
SwitchHC138(5);
P0 = 0x00;
DelayL(100);
SwitchHC138(4);
P0 = 0xff;
}
void main()
{
Init();
Init_INT0();
while(1)
{
Working();
Light();
}
}