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; //2s
const 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);
}
else
digitalWrite(B,HIGH);
}
void Isr()//中断函数
{
digitalWrite(B,LOW);
flag=0;
}
while(digitalRead(SW)==1&&analogRead(Ry)<800){ //调Time
if(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;//10ms
LiquidCrystal 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){ //调Time
if(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;//10ms
LiquidCrystal 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){ //调Time
if(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){ //调Time
if(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;//10ms
LiquidCrystal 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){ //调Time
if(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;
}
}