1、定义
由于某种事件的发生,处理器暂停执行当前的程序,转而执行另一程序,以处理发生的事件,处理完毕后又返回原程序继续作业。
2、中断优先级
中断响应原则:
①首先响应高优先级的中断请求;
②如果优先级相同,按查询次序响应排在前面的中断;
③正在进行的中断过程不能被新的同级或低优先级的中断请求所中断;
④正在进行的低优先级中断过程,能被高优先级中断请求所中断。
3、中断的作用:
处理突发事件;安排事件处理的优先级。
注:
- 中断过程中delay()不起作用,millis函数不包括中断时间,Arduino开发板接收到的串口数据可能丢失;
- 中断服务程序不能返回任何数值。所以应尽量在中断服务程序中使用全局变量;
- 中断服务程序中涉及的变量应声明为volatile类型。
4、中断类型:
(1)定时器中断:设定一个间隔时间,单片机定时器每个相同的间隔时间会产生一次定时器中断,单片机处理器接收到定时器中断信号后执行相应的中断处理程序;“间隔固定时间中断”
#include<TimerOne.h>Timer1.initialize(interval) //interval是时间间隔,整数,以微秒为单位Timer1.attachInterrupt(ISR) //附上中断处理程序void ISR() //ISR是中断处理程序,空函数,无参数无返回值
注:
①使用了TimerOne库,则板子上的 pin 9 和 pin 10 就不能再用做 PWM 输出;
②Servo库不能和TimerOne库一起使用;
③使用 TimerOne 库只能设定一件要定时做的事, 后面的 attachInterrupt( ) 会盖掉前面的 attachInterrupt( )。
(2)外部中断:单片机外部中断引脚的电平的特定变化产生的中断事件;“让它中断就中断”
中断配置函数: attachInterrupt(channel,ISR,mode)
参数:
channel:中断通道号,Ardunio UNO中通道编号0/1分别对应板子上引脚号2/3
ISR:用户自定义的中断处理程序,空函数
mode:中断触发模式
LOW: 当引脚为低电平时触发中断服务程序
CHANGE: 当引脚电平发生变化时触发中断服务程序
RISING: 当引脚电平由低电平变为高电平时触发中断服务程序
FALLING: 当引脚电平由高电平变为低电平时触发中断服务程序
#include <TimerOne.h>const long interval = 2000000; //2sconst int R=7,B=6,G=5;int counter=0;void setup(){pinMode(R,OUTPUT);pinMode(B,OUTPUT);pinMode(G,OUTPUT);digitalWrite(R,LOW);digitalWrite(B,LOW);digitalWrite(G,LOW);Timer1.initialize( interval ); // 初始化,每2秒产生一次定时器中断Timer1.attachInterrupt( Isr );}void Isr( ){if(counter==0){digitalWrite(R,HIGH);digitalWrite(G,LOW);digitalWrite(B,LOW);counter++;}else if(counter==1){digitalWrite(R,LOW);digitalWrite(G,HIGH);digitalWrite(B,LOW);counter++;}else{digitalWrite(R,LOW);digitalWrite(G,LOW);digitalWrite(B,HIGH);counter=0;}}void loop(){}
const int B=7;const int interruptPin=2; //外部中断引脚int counter=0;int flag=0;void setup(){pinMode(B, OUTPUT);pinMode(interruptPin, INPUT_PULLUP);digitalWrite(B,HIGH);attachInterrupt(0, Isr, FALLING);//当int.0电平由高变低时,触发中断函数Isr}void loop(){if(flag==0){flag=1;delay(1000);digitalWrite(B,HIGH);}elsedigitalWrite(B,HIGH);}void Isr()//中断函数{digitalWrite(B,LOW);flag=0;}
while(digitalRead(SW)==1&&analogRead(Ry)<800){ //调Timeif(analogRead(Rx)>800){if(Time<9){Time++;SetTimer();}else{Time=0;SetTimer();}}else if(analogRead(Ry)<200){if(Time>0){Time--;SetTimer();}else{Time=9;SetTimer();}}} //调Time结束
#include <TimerOne.h>#include <LiquidCrystal.h>const int Rx=0,Ry=1,SW=3;const int rs=13,en=12,d4=11,d5=8,d6=7,d7=4;int flag=0,state=2,Time=0,count=0;const long interval=10000;//10msLiquidCrystal LCD(rs, en, d4, d5, d6, d7);void wait(){LCD.print("Wait...");delay(1000);LCD.clear();}void SetTimer(){LCD.setCursor(0,0);LCD.print("Timer");LCD.setCursor(0,1);LCD.print(Time);}void setup() {LCD.begin(16,2);LCD.clear();LCD.setCursor(0,0);wait();pinMode(SW,INPUT_PULLUP);attachInterrupt(1, Isr, FALLING);//当int.0电平由高变低时,触发中断函数Isr}void loop() {if(state==1){wait();state=2;return;}if(state==2){SetTimer();//调Timer时间while(digitalRead(SW)==1&&analogRead(Ry)<800){ //调Timeif(flag==0){flag=1;if(analogRead(Rx)>800){if(Time<9){Time++;SetTimer();}else{Time=0;SetTimer();flag=0;}}}else if(analogRead(Ry)<200){if(Time>0){Time--;SetTimer();}else{Time=9;SetTimer();}}} //调Time结束count=Time*1000;state=3;return;}if(state==3){Timer1.initialize( interval ); // 初始化,每10ms产生一次定时器中断if(count>0){Timer1.attachInterrupt( Isrtime );}else{state=4;return;}}if(state==4){LCD.clear();LCD.setCursor(0,0);LCD.print("Beep");delay(100);if(SW==0){state=1;return;}}}void Isr(){wait();state=2;}void Isrtime(){attachInterrupt(Rx, Isr2, RISING);if(count>0){LCD.setCursor(0,0);LCD.print("Timer");LCD.setCursor(0,1);LCD.print(count);count=count-10;}else{return;}}void Isr1(){}void Isr2(){LCD.setCursor(0,0);LCD.print("Timer");LCD.setCursor(0,1);LCD.print(count);if(analogRead(Rx)<300){Timer1.detachInterrupt();}}
#include <TimerOne.h>#include <LiquidCrystal.h>const int Rx=0,Ry=1,SW=3;const int rs=13,en=12,d4=11,d5=8,d6=7,d7=4;int flag1=0,flag2=0,state=2,Time=0,count=0;const long interval=10000;//10msLiquidCrystal LCD(rs, en, d4, d5, d6, d7);void wait(){LCD.print("Wait...");delay(1000);LCD.clear();}void SetTimer(){LCD.setCursor(0,0);LCD.print("Timer");LCD.setCursor(0,1);LCD.print(Time);}void setup() {Serial.begin(9600);LCD.begin(16,2);LCD.clear();LCD.setCursor(0,0);wait();pinMode(SW,INPUT_PULLUP);attachInterrupt(1, Isr, FALLING);//当int.0电平由高变低时,触发中断函数Isr}void loop() {if(state==1){wait();state=2;return;}else if(state==2){SetTimer();//调Timer时间if(analogRead(Ry)<800){ //调Timeif(analogRead(Rx)>800){if(Time<9){Time++;SetTimer();}else{Time=0;SetTimer();}delay(500);Serial.println(Time);Serial.println(count);Serial.println(state);}else if(analogRead(Rx)<300){if(Time>0){Time--;SetTimer();}else{Time=9;SetTimer();}delay(500);Serial.println(Time);Serial.println(count);Serial.println(state);}return;}else{state=3;count=Time*1000;Serial.println(Time);Serial.println(count);Serial.println(state);return;}}else if(state==3){Serial.println(state);Timer1.initialize( interval ); // 初始化,每10ms产生一次定时器中断Serial.println(state);if(count>0){Timer1.attachInterrupt( Isrtime );}else{state=4;return;}}else if(state==4){LCD.clear();LCD.setCursor(0,0);LCD.print("Beep");delay(100);if(SW==0){state=1;return;}}}void Isr(){wait();state=2;}void Isrtime(){if(count>0&&SW==1){if(flag2==0){if(analogRead(Rx)<800&&analogRead(Rx)>400){LCD.setCursor(0,0);LCD.print("Timer");LCD.setCursor(0,1);LCD.print(count);count=count-10;}if(analogRead(Rx)>600){flag2=1;LCD.setCursor(0,0);LCD.print("Timer");LCD.setCursor(0,1);LCD.print(count);}}if(analogRead(Rx)<400){flag2=0;}}else if(SW==0){state=1;return;}else{return;}}
else if(state==2){SetTimer();//调Timer时间if(analogRead(Ry)<800){ //调Timeif(analogRead(Rx)>800){if(Time<9){Time++;SetTimer();}else{Time=0;SetTimer();}delay(500);Serial.println(Time);Serial.println(count);Serial.println(state);}else if(analogRead(Rx)<300){if(Time>0){Time--;SetTimer();}else{Time=9;SetTimer();}delay(500);Serial.println(Time);Serial.println(count);Serial.println(state);}return;}else{state=3;count=Time*1000;Serial.println(Time);Serial.println(count);Serial.println(state);return;}}
void Isrtime(){if(count>0){if(flag==0){if(analogRead(Rx)<800&&analogRead(Rx)>400){LCD.clear();LCD.setCursor(0,0);LCD.print("Timer");LCD.setCursor(0,1);LCD.print(count);count=count-10;}else if(analogRead(Rx)>800){flag=1;LCD.clear();LCD.setCursor(0,0);LCD.print("Timer");LCD.setCursor(0,1);LCD.print(count);}}else if(analogRead(Rx)<400){flag=0;}}else{return;}}
void Isrtime(){if(count>0){LCD.setCursor(0,0);LCD.print("Timer");LCD.setCursor(0,1);LCD.print(count);count=count-10;}else{return;}}
#include <TimerOne.h>#include <LiquidCrystal.h>const int Rx=0,Ry=1,SW=3;const int rs=13,en=12,d4=11,d5=8,d6=7,d7=4;int flag=0,state=2,Time=0,count=0;const long interval=10000;//10msLiquidCrystal LCD(rs, en, d4, d5, d6, d7);void wait(){LCD.print("Wait...");delay(1000);LCD.clear();}void SetTimer(){LCD.setCursor(0,0);LCD.print("Timer");LCD.setCursor(0,1);LCD.print(Time);}void Isr(){wait();state=2;}void setup() {Serial.begin(9600);LCD.begin(16,2);LCD.clear();LCD.setCursor(0,0);wait();pinMode(SW,INPUT_PULLUP);attachInterrupt(1,Isr,FALLING);//当int.0电平由高变低时,触发中断函数Isr}void loop() {if(state==1){wait();state=3;return;}else if(state==2){SetTimer();//调Timer时间if(analogRead(Ry)<800){ //调Timeif(analogRead(Rx)>800){if(Time<9){Time++;SetTimer();}else{Time=0;SetTimer();}delay(500);Serial.println(Time);Serial.println(count);Serial.println(state);}else if(analogRead(Rx)<300){if(Time>0){Time--;SetTimer();}else{Time=9;SetTimer();}delay(500);Serial.println(Time);Serial.println(count);Serial.println(state);}return;}else{state=3;count=Time*1000;Serial.println(Time);Serial.println(count);Serial.println(state);return;}}else if(state==3){Timer1.initialize( interval ); // 初始化,每10ms产生一次定时器中断if(count>0){Timer1.attachInterrupt( Isrtime );}else{state=4;return;}}else if(state==4){LCD.clear();LCD.setCursor(0,0);LCD.print("Beep");delay(100);if(SW==0){state=1;return;}}}void Isrtime(){if(count>0){if(flag==0){if(analogRead(Rx)<800&&analogRead(Rx)>400){LCD.clear();LCD.setCursor(0,0);LCD.print("Timer");LCD.setCursor(0,1);LCD.print(count);count=count-10;}else if(analogRead(Rx)>800){flag=1;LCD.clear();LCD.setCursor(0,0);LCD.print("Timer");LCD.setCursor(0,1);LCD.print(count);}}else if(analogRead(Rx)<400){flag=0;}}else{return;}}
