外中断的应用

前言

软件基础操作参考这篇博客:

LED数码管的静态显示与动态显示(Keil+Proteus)-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/weixin_64066303/article/details/134101256?spm=1001.2014.3001.5501实验一:P1口上接8个LED灯,在外部中断0引脚接一只按钮开关K1。采用低电平触发方式,当程序启动时,P1口上的8只LED灯全亮,每按下一次按钮开关K1,是的引脚接地,产生一个外中断请求,在中断服务程序中,让低4位的LED与高4位的LED交替闪烁5次。然后中断返回,控制8只LED再次全亮。

实验二:P1口上接8个LED灯,在外部中断0输入引脚接一只按钮开关K1,在外部中断1输入引脚接一只按钮开关K2。当K1和K2均未按下时,P1口的8只LED呈流水灯显示;当K1按下再松开时,P1口的8只LED按照高4位和低4位交替闪烁10次,然后恢复到流水灯状态;当K2按下在松开时,P1口的8只LED按照整体闪烁10次,然后再恢复到流水灯显示,两个外中断的优先级相同且都采用下降沿触发方式。(K1和K2不能同时按下)

实验三:P1口上接8个LED灯,在外部中断0输入引脚接一只按钮开关K1,在外部中断1输入引脚接一只按钮开关K2。当K1和K2均未按下时,P1口的8只LED呈流水灯显示,当K1按下再松开时,P1口的8只LED按照高4位和低4位交替闪烁,当K2按下在松开时,P1口的8只LED按照整体闪烁5次。当按下K1时,产生一个低优先级的外部中断0请求(下降沿触发),进入外部中断0服务程序,此时按一下K2,产生一个高优先级的外部中断1请求(下降沿触发),当外部中断1结束后返回继续执行外部中断0服务程序。

单一外中断的应用

keil

根据实验的要求,在主函数里面就是一直保持P1口全亮,采用的是共阳极,所以在程序中给0就是表示全亮。

在中断函数中,要交替闪烁5次就是把闪烁的部分循环5次即可,实现高4位和低4位交替闪烁其实就是高四位亮和低四位亮交替,前面提到给0就表示LED亮,所以就是先后给P1口赋值0x0F和0xF0,这要注意的是延迟部分,这个可能需要自己根据电脑来调试,延时时间太短的话,人眼捕捉不到这么快的变化,所以导致看到的是没有交替就结束了,所以这个需要自己来调整延时的时间。

#include<reg51.h>
#define uchar unsigned char
//延时函数
void Delay(unsigned int i){
	unsigned int j;
	for(;i>0;i--){
		for(;j<1314;j++);
	}
}

//外部中断0,中断向量0003H
void int0() interrupt 0 using 0{
	uchar m;
	EX0=0;//禁止外部中断0
	for(m=0;m<5;m++){//交替闪烁5次
		P1=0x0F;//低4位LED灭,高4位LED亮
		Delay(111213141516171819);//延时时间设置长一点
		P1=0xF0;//低4位LED亮,高4位LED灭
		Delay(111213141516171819);//延时时间设置长一点
	}
	EX0=1;//中断返回前,打开外部中断0
}

void main(){
	EA=1;//总中断允许
	EX0=1;//INT0开中断
	IT0=0;//选择外部中断为低电平触发方式
	while(1){
		P1=0;
	}
}

Proteus

所需Proteus元器件。

元件名称Proteus关键字
51单片机AT89C51
复位按钮BUTTON
电阻RES
黄色LED灯LED-YELLOW
电源POWER
电阻GROUND

这里要注意的是设置左边电阻的阻值,如果阻值太高会导致LED灯不亮。

两个外中断的应用

keil

当需要多个中断源时,只需要增加相应的中断服务函数即可。

就是之前按钮未按下前LED灯是全亮的,如今采用的是流水灯,按下K1高低位交替闪烁10次,按下k2整体闪烁10次,之后继续流水灯,流水灯部分可以采用数组也可以采用移位来实现。

#include<reg51.h>
#define uchar unsigned char
//延时函数
void Delay(unsigned int i){
	unsigned int j;
	for(;i>0;i--){
		for(;j<1314;j++);
	}
}

void main(){
	uchar i;
	//流水灯显示数据数组
	uchar display[9]={0xFF,0xFe,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};
	EA=1;//总中断允许
	EX0=1;//允许INT0中断
	EX1=1;//允许INT1中断
	IT0=1;//选择INT0为下降沿触发
	IT1=1;//选择INT1为下降沿触发
	IP=0;//两个外部中断均为低优先级
	while(1){
		for(i=0;i<9;i++){
			Delay(111213141516171819);
			P1=display[i];
		}
	}
}
//外中断0的中断服务函数(高、低4位显示10次)
void int0() interrupt 0 {
	uchar i;
	EX0=0;//禁止外部中断0
	for(i=0;i<10;i++){
		P1=0x0F;
		Delay(111213141516171819);
		P1=0xF0;
		Delay(111213141516171819);
	}
	EX0=1;//中断返回前,打开外部中断0
}
//外中断1的中断服务函数(整体闪烁显示)
void int1() interrupt 2 {
	uchar i;
	EX1=0;//禁止外部中断1
	for(i=0;i<10;i++){
		P1=0xFF;
		Delay(111213141516171819);
		P1=0;
		Delay(111213141516171819);
	}
	EX1=1;//中断返回前,打开外部中断1
}

Proteus

所需要元器件参考单一外中断的应用部分的,就是在前者的基础上添加了一个按钮。

中断嵌套的应用 

keil

当K1按下之后会执行中断0服务函数,此时如果再按下K2,因为中断1的优先级高于中断0,故而会跳转执行中断1的服务函数,执行外之后因为中断0的服务程序还没执行完(没有表明执行次数,表示一直执行),所以会跳转执行中断0的服务函数,变为高低4为交替闪烁。

这个要注意的是,如果先按下K2的话,当中断1的服务程序执行完成之后会跳转到主函数,总之要记住是返回被打断的那个程序。

#include<reg51.h>
#define uchar unsigned char
//延时
void Delay(unsigned int i){
	unsigned int j;
	for(;i>0;i--){
		for(j=0;j<125;j++){;
		}
	}
}

void main(){
	uchar i;
	uchar display[9]={0xFF,0xFe,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};//流水灯显示数组
	while(1){
		EA=1;//总中断允许
		EX0=1;//允许外部中断0
		EX1=1;//允许外部中断1
		IT0=1;//选择外部中断0为下降沿触发
		IT1=1;//选择外部中断1为下降沿触发
		PX0=0;//设置中断0为低优先级
		PX1=1;//设置中断1为高优先级
		for(i=0;i<9;i++){
			Delay(500);
			P1=display[i];//流水灯
		}
	}
}
//外部中断0,高低4位交换闪烁
void int0() interrupt 0{
	while(1){
		P1=0x0F;
		Delay(400);
		P1=0xF0;
		Delay(400);
	}
}

//外部中断1,整体闪烁
void int1() interrupt 2{
	uchar i;
	for(i=0;i<5;i++){
		P1=0x00;
		Delay(500);
		P1=0xFF;
		Delay(500);
	}
}

原理图和“两个外中断就是一致的了”,就是实现的效果不一样。 

参考链接

2.单片机基础知识讲解--中断服务函数 - 知乎 (zhihu.com)icon-default.png?t=N7T8https://zhuanlan.zhihu.com/p/618472480?utm_id=0

51单片机中断笔记 - 知乎 (zhihu.com)icon-default.png?t=N7T8https://zhuanlan.zhihu.com/p/593229489

总结

继续加油,一切都是最好的安排。

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

封奚泽优

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值