题目背景
定义一个 Working()
函数,使L1指示灯不断闪烁。将P32引脚定义成外部中断功能,按下S5按键就会产生外部中断触发信号,在中断响应函数中,点亮L8指示灯,延时较长一段时间后熄灭,该功能用两种方法实现:
- 直接在中断函数中延时。
- 在中断服务中标志变量,在外部进行延时。
分析
中断函数格式
void InterruptName() interrupt x
{...}
J5跳帽
J5跳帽需要接到2、3引脚上。让S5接到P32/INT0,S4接到P33/INT1。
两种方式差异
方式1的中断触发信号,无论L1是亮还是灭都会产生。也就是只要按下S5按键后,无论L1是什么状态,L1总会保持当前的状态,然后L8点亮并延时一段时间。
方式2就不同了。方式二产生中断后,仅将 stat_int
赋值为1,不执行其余的操作。然后在 main()
中LEDINT()
查询 stat_int
的值,一旦发现变成1就将L8点亮并延时一段时间。因为 LEDINT()
在 Working()
后面执行,所以L8点亮的时候,L1一定是熄灭的状态。
代码1
#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit L1 = P0 ^ 0;
sbit L8 = P0 ^ 7;
void Delay(uint t)
{
while(t -- );
while(t -- );
while(t -- );
while(t -- );
}
void HC138(uchar channel)
{
switch(channel)
{
case 4:
P2 = (P2 & 0x1f) | 0x80;
break;
case 5:
P2 = (P2 & 0x1f) | 0xa0;
break;
case 6:
P2 = (P2 & 0x1f) | 0xc0;
break;
case 7:
P2 = (P2 & 0x1f) | 0xe0;
break;
}
}
void Working()
{
HC138(4);
L1 = 0;
Delay(60000);
L1 = 1;
Delay(60000);
}
// 中断初始化
void Init_INT0()
{
IT0 = 1;
EX0 = 1;
EA = 1;
}
// 中断函数
void Service_INT0() interrupt 0
{
L8 = 0;
Delay(60000);
Delay(60000);
Delay(60000);
Delay(60000);
Delay(60000);
Delay(60000);
L8 = 1;
}
void main()
{
Init_INT0();
while(1)
{
Working();
}
}
代码2
#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit L1 = P0 ^ 0;
sbit L8 = P0 ^ 7;
void Delay(uint t)
{
while(t -- );
while(t -- );
while(t -- );
while(t -- );
}
void HC138(uchar channel)
{
switch(channel)
{
case 4:
P2 = (P2 & 0x1f) | 0x80;
break;
case 5:
P2 = (P2 & 0x1f) | 0xa0;
break;
case 6:
P2 = (P2 & 0x1f) | 0xc0;
break;
case 7:
P2 = (P2 & 0x1f) | 0xe0;
break;
}
}
void Working()
{
HC138(4);
L1 = 0;
Delay(60000);
L1 = 1;
Delay(60000);
}
// 中断初始化
void Init_INT0()
{
IT0 = 1;
EX0 = 1;
EA = 1;
}
// 中断函数
uchar stat_int = 0;
void Service_INT0() interrupt 0
{
stat_int = 1;
}
void LEDINT()
{
if (stat_int == 1)
{
L8 = 0;
Delay(60000);
Delay(60000);
Delay(60000);
Delay(60000);
Delay(60000);
Delay(60000);
L8 = 1;
}
stat_int = 0;
}
void main()
{
Init_INT0();
while(1)
{
Working();
LEDINT();
}
}