中断的基本概念
百度百科上是这样说的,当中央处理机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模块领域博主
后续模块更新中。。。