蓝桥杯单片机比赛学习:5、中断系统之外部中断的基本原理

中断的基本概念

百度百科上是这样说的,当中央处理机CPU正在处理某件事的时候外界发生了紧急事件请求,要求CPU暂停当前的工作,转而去处理这个紧急事件,处理完以后,再回到原来被中断的地方,继续原来的工作,这样的过程称为中断。通俗点说,就是当你在看书的时候有人敲门,这时你会打断看书去开门,之后再继续看书,这个过程就是中断。一般比较高级的单片机都会有中断嵌套,当CPU正在处理一个中断源请求的时候(执行相应的中断服务程序),发生了另外一个优先级比它还高的中断源请求。如果CPU能够暂停对原来中断源的服务程序,转而去处理优先级更高的中断请求源,处理完以后,再回到原低级中断服务程序,这样的过程称为中断嵌套。这里的中断嵌套在蓝桥杯比赛中并不常用,所以我们这里只需要了解一下就好。

我这里使用的是蓝桥杯4T的最新板子,使用的芯片是STC15F2K60S2系列。单片机提供了14个中断请求源,它们分别是:外部中断0(INT0)、定时器0中断、外部中断1(INT1)、定时器1中断、串口1中断、A/D转换中断、低压检测(LVD)中断、CCP/PWM/PCA中断、串口2中断、SPI中断、外部中断2(INT2)、外部中断3(INT3),定时器2中断以及外部中断4(INT4)。我们这里使用最多的是外部中断0、定时器0中断、外部中断1、定时器1中断、串口1中断。

中断系统的内部结构

如上图,我只是截取了我们比赛中使用比较多的几个中断,如果想了解更多请去看一下 STC15F2K60S2的使用手册。上图中的中断0和中断1为外部中断,它分为边沿触发(上升沿和下降沿)和电平触发(高电平和低电平),主要是通过外部信号触发中断(如按键)。使用中断前都需要初始化。例如外部中断初始化过程为:1、IT0=1(使用外部中断0)2、EX0=1(外部中断0开关闭合)  3、EA=1(总中断开关闭合)4、写中断服务函数(中断触发时,CPU执行的函数,执行后返回中断点)中断服务函数与其他函数不同,在写函数时后面需要加上中断号,如下图

 外部中断的使用

开发板上的S5(P3^2)按键连接到外部中断0(INT0),S4(P3^3)按键连接到外部中断1(INT1)现在我们使用外部中断0来举例,外部中断1类似。

首先,我们先初始化外部中断0,写一个外部中断初始化函数。

void INT0_Init(void)
{
	IT0=1;				/* 选择外部中断的触发方式(1:仅下降沿,0:上升沿和下降沿) */
	EX0=1;				/* 使能INT0(外部中断0) */
	EA=1;				/* 使能总中断 */
}

其次,写一个外部中断0的中断服务函数,内容是你想在中断时操作的东西(每中断一次判断flag的数值)。

void Service_INT0()  interrupt 0
{
    /* 中断后需要操作的内容 */
	if(flag==0)
		flag=1;
	else if(flag==1)
	{
		flag=0;
		slect_138_573(4,0xff);
	}
		
}

代码实现: 

 题目要求:L1以每500ms闪烁,按一下S5 L8亮,再按一下S5 L8灭。

#include "stc15f2k60s2.h"
#include "intrins.h"

void Delay1ms()		//@12.000MHz
{
	unsigned char i, j;

	i = 12;
	j = 169;
	do
	{
		while (--j);
	} while (--i);
}

void delay_ms(int x)
{
	while(x--)
	{
		Delay1ms();
	}
}

/* 选择通道并且输入数据 */
void slect_138_573(unsigned char channel, unsigned char dat)
{
	P0 = 0x00;
	P0 = dat;										/* 这里用P0而不用其他端口是因为我们操作LED、数码管、继电器、蜂鸣器都是对P0进行操作 */
	switch(channel)							        /* 选择通道 */
	{
		case 4:										/* 使Y4输出低电平0,也就是操作LED */
			P2 = (P2 & 0x1f) | 0x80;                /* (P2 & 0x1f)就是将前3位清0,再操作前3位。将0x80转为2进制1000 0000,这里只看前3位100就是Y4 */
		break;
		case 5:										/* 使Y5输出低电平0,也就是操作继电器和蜂鸣器 */
			P2 = (P2 & 0x1f) | 0xa0;
		break;
		case 6:										/* 使Y6输出低电平0,也就是操作8个数码管 */
			P2 = (P2 & 0x1f) | 0xc0;
		break;
		case 7:										/* 使Y7输出低电平0,也就是操作8个数码管中的1个数码管显示值 */
			P2 = (P2 & 0x1f) | 0xe0;
		break;
		case 0:										/* 关闭所有通道 */
			P2 = (P2 & 0x1f) | 0x00;
		break;
	}
	P2 = (P2 & 0x1f) | 0x00;		/* 使用后,关闭所有通道 */
	
}

void INT0_Init(void)
{
	IT0=1;				/* 选择外部中断的触发方式(1:仅下降沿,0:上升沿和下降沿) */
	EX0=1;				/* 使能INT0(外部中断0) */
	EA=1;				/* 使能总中断 */
}

unsigned char flag=0;
void Service_INT0(void)  interrupt 0
{
	if(flag==0)
		flag=1;
	else if(flag==1)
	{
		flag=0;
		slect_138_573(4,0xff);
	}
		
}

void led(void)
{
	if(flag==0)
	{
		slect_138_573(4,P0^0x01);
		delay_ms(500);
	}
	else if(flag==1)
	{
		slect_138_573(4,0x7f);
		delay_ms(1500);
		slect_138_573(4,0xff);
	}
}


void System_init(void)
{
	slect_138_573(4,0xff);
	slect_138_573(5,0x00);
	INT0_Init();
	P0=0xff;
}

void main(void)
{
	System_init();
	while(1)
	{
		led();
	}
}

本人认为此处不太重要,考试时很少考,而且按下按键时会有抖动,也会影响实验造成实验不准,所以说此部分考题少,考的也少。以上仅为个人观点。如有不懂请到本人主页看前几篇文章。Do My Best的博客_CSDN博客-蓝桥杯单片机比赛学习,sim800c模块领域博主

后续模块更新中。。。 

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Do My Best

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

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

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

打赏作者

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

抵扣说明:

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

余额充值