比如说我正在厨房用煤气烧一壶水,这样就只能守在厨房里,苦苦等着水开——如果水溢出来浇灭了煤气,有可能就要发生一场灾难了。
门外忽然又传来了铿锵有力的歌声,我最喜欢的天龙八部要开演了,听着水壶发出“咕嘟咕嘟”的声音,我清楚:除非等到水开,否则没有我享受人生的时候。
在这个场景中,我是唯一具有处理能力的主体,不管是烧水、还是看电视,同一个时间点上我只能干一件事情。但是,在我专心致志干一件事情时,总有许多或紧迫或不紧迫的事情突然出现在面前,都需要去关注,有些还需要我停下手头的工作马上去处理。只有在处理完之后,方能回头完成先前的任务。
中断机制不仅赋予了我处理意外情况的能力,如果我能充分发挥这个机制的妙用,就可以“同时”完成多个任务了。
事实上烧水需要10分钟完成,但是提下水壶和关煤气我只要几秒钟就可以完成。为了这几秒,我需要在厨房等候10分钟。如果使用闹钟定时10分钟,10分钟一到,闹钟就会提醒我该去关煤气了,那么我就可以去安心看电视了。
实际上就是用了闹钟这样一个中断信号来提示我完成提水壶和关煤气的任务。
51单片机共有6个中断源,分别如下:
INT0——外部中断0,由P3_2端口引入,低电平或者下降沿引起;中断级别最高;C语言使用序号为0;
T0——定时器/计数器0,由T0计数器计数回零引起;中断级别第二;C语言使用序号为1;
INT1——外部中断1,由P3_3端口引入,低电平或者下降沿引起;中断级别第三;C语言使用序号为2;
T1——定时器/计数器1,由T1计数器计数回零引起;中断级别第四;C语言使用序号为3;
TI/RI——串行口中断,由串行口完成一帧字符发送/接受后引起;中断级别第五;C语言使用序号为4;
T2——定时器/计数器2,由T2计数器计数回零引起;中断级别第六;C语言使用序号为5;
下面先简单写一个不用中断实行的数码管秒表程序,定时器的使用可以参考我的这边文章: (51单片机定时器使用)[https://cloud.tencent.com/developer/article/1563103]
# include <8052.h>
# define ADDR0 P1_0
# define ADDR1 P1_1
# define ADDR2 P1_2
# define ADDR3 P1_3
# define ENLED P1_4
unsigned char __code LedChar[] = { //数码管显示字符转换表
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
};
unsigned char LedBuff[6] = { //数码管显示缓冲区,初值0xFF确保启动时都不亮
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
void main() {
unsigned char i = 0; //动态扫描的索引
unsigned int cnt = 0; //记录T1中断次数
unsigned long sec = 0; //记录经过的秒数
ENLED = 0;
ADDR3 = 1;
TMOD = 0x01; //设置T1为模式1
TH1 = 0xCF; //为T1赋初值0xCF67,为1ms
TL1 = 0x67;
TR1 = 1; //启动T1
while(1) {
if (TF1 == 1) { //判断T1是否溢出
TF1 = 0; //T1溢出后,清零中断标志,并重新赋值
TH1 = 0xCF;
TL1 = 0x67;
TR1 = 1;
cnt ++; //计数值自加1
if (cnt >= 1000) { //判断T1溢出是否达到1000次
cnt = 0; //达到1000次后计数值清零
sec ++; //秒计数自加1
/*以下代码将sec按十进制位从低到高依次提取并转为数码管显示字符*/
LedBuff[0] = LedChar[sec%10];
LedBuff[1] = LedChar[sec/10%10];
LedBuff[2] = LedChar[sec/100%10];
LedBuff[3] = LedChar[sec/1000%10];
LedBuff[4] = LedChar[sec/10000%10];
LedBuff[5] = LedChar[sec/100000%10];
}
}
P0 = 0xFF; //数码管消隐
/*以下代码完成数码管动态扫描刷新*/
switch(i) {
case 0: ADDR2=0; ADDR1=0; ADDR0=0; i++; P0=LedBuff[0]; break;
case 1: ADDR2=0; ADDR1=0; ADDR0=1; i++; P0=LedBuff[1]; break;
case 2: ADDR2=0; ADDR1=1; ADDR0=0; i++; P0=LedBuff[2]; break;
case 3: ADDR2=0; ADDR1=1; ADDR0=1; i++; P0=LedBuff[3]; break;
case 4: ADDR2=1; ADDR1=0; ADDR0=0; i++; P0=LedBuff[4]; break;
case 5: ADDR2=1; ADDR1=0; ADDR0=1; i=0; P0=LedBuff[5]; break;
default: break;
}
}
}
下面我们将使用中断来实现
# include <8052.h>
# define ADDR0 P1_0
# define ADDR1 P1_1
# define ADDR2 P1_2
# define ADDR3 P1_3
# define ENLED P1_4
unsigned char __code LedChar[] = { //数码管显示字符转换表
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
};
unsigned char LedBuff[6] = { //数码管显示缓冲区,初值0xFF确保启动时都不亮
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
unsigned char i = 0; //动态扫描的索引
unsigned char flag1s = 0;//1秒定时标志
unsigned int cnt = 0; //记录T1中断次数
void main() {
unsigned long sec = 0;//记录经过的秒数
EA = 1; //使能总中断
ENLED = 0; //使能U3
ADDR3 = 1; //因为需要动态改变ADDR0-2的值,所以不需要再初始化了
TMOD = 0x10; //设置T1为模式1
TH1 = 0xFC; //为T1赋初值0xFC67,定时1ms
TL1 = 0x67;
ET1 = 1; //使能T1中断
TR1 = 1; //启动T1
while(1) {
if (flag1s == 1) { //判断1秒定时标志
flag1s = 0; //1秒定时标志清零
sec ++; //秒计数自减1
/*以下代码将sec按十进制位从低到高依次提取并转为数码管显示字符*/
LedBuff[0] = LedChar[sec%10];
LedBuff[1] = LedChar[sec/10%10];
LedBuff[2] = LedChar[sec/100%10];
LedBuff[3] = LedChar[sec/1000%10];
LedBuff[4] = LedChar[sec/10000%10];
LedBuff[5] = LedChar[sec/100000%10];
}
}
}
/* 定时器1中断服务函数 */
void InterruptTime1() __interrupt 3 {
TH1 = 0xCF; //重新加载初值
TL1 = 0x67;
cnt++; //中断次数计数值加1
if (cnt >= 1000) { //中断1000次即1秒
cnt = 0; //清零计数值以重新开始下1秒计时
flag1s = 1; //设置1秒定时标志为1
}
/*以下代码完成数码管动态扫描刷新*/
P0 = 0xFF; //显示消隐
switch(i) {
case 0: ADDR2=0; ADDR1=0; ADDR0=0; i++; P0=LedBuff[0]; break;
case 1: ADDR2=0; ADDR1=0; ADDR0=1; i++; P0=LedBuff[1]; break;
case 2: ADDR2=0; ADDR1=1; ADDR0=0; i++; P0=LedBuff[2]; break;
case 3: ADDR2=0; ADDR1=1; ADDR0=1; i++; P0=LedBuff[3]; break;
case 4: ADDR2=1; ADDR1=0; ADDR0=0; i++; P0=LedBuff[4]; break;
case 5: ADDR2=1; ADDR1=0; ADDR0=1; i=0; P0=LedBuff[5]; break;
default: break;
}
}
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有