弘毅 发表于 2014-4-25 16:18:17

OCROBOT入门教程022--外部中断的使用

本帖最后由 董董soul 于 2016-10-27 11:14 编辑

中断的基本原理

要搞清楚什么是中断,我们可以从生活中的一个例子了解下。

你正在家里看电视,突然家里座机响了,你起身去接电话,接完电话后继续回来看电视。
这就是生活中的中断现象,也就是一个正在做的事情被外部的事情打断,当执行完外部事情后,继续做原本的事情。

什么是中断?

所谓中断,是指CPU在正常运行程序时,由于内部/外部事件或由程序预先安排的事件,引起CPU中断正在运行的程序,而转到为内部/外部事件或为预先安排的事件服务的程序中去,服务完毕,再返回去执行波暂时中断的程序

由于某个事件的发生,CPU暂停当前正在执行的程序,转而执行处理该事件的一个程序。该程序执行完成后,CPU接着执行被暂停的程序。这个过程称为中断。
根据中断源的位置,有两种类型的中断。有的中断源在CPU的内部,称为内部中断。大多数的中断源在CPU的外部,称为外部中断。
根据中断引脚的不同,或者CPU响应中断的不同条件,也可以把中断划分为可屏蔽中断和不可屏蔽中断两种。

使用中断的好处

1、 实行分时操作提高 CPU 的效率只有当服务对象向 CPU 发出中断申请时才去为它服务这样我们就可以利用中断功能同时为多个对象服务从而大大提高了 CPU 的工作效率
2、 实现实时处理

利用中断技术各个服务对象可以根据需要随时向 CPU 发出中断申请及时发现和处理中断请求。

在MANGO中,有两个可以使用的外部中断,0(数字引脚2)和1(数字引脚3),本次例子中我们使用D2引脚作为中断引脚,使用D12引脚控制LED。原理图如下:



int pbIn = 0;                  // 定义中断引脚为0,也就是D2引脚
int ledOut = 12;                // 定义输出指示灯引脚
volatile int state = LOW;      // 定义默认输入状态

void setup()
{               
// 置ledOut引脚为输出状态
pinMode(ledOut, OUTPUT);

// 监视中断输入引脚的变化
attachInterrupt(pbIn, stateChange, CHANGE);
}

void loop()                     
{
// 模拟长时间运行的进程或复杂的任务。
for (int i = 0; i < 100; i++)
{
    // 什么都不做,等待10毫秒
    delay(10);
}
}

void stateChange()
{
state = !state;
digitalWrite(ledOut, state);
}


http://player.youku.com/player.php/sid/XNzE5NzAzNTky/v.swf

中断命令语法介绍
attachInterrupt(interrupt, function, mode)

interrupt:中断引脚数
function:中断发生时调用的函数,此函数必须不带参数和不返回任何值。该函数有时被称为中断服务程序。
mode:定义何时发生中断以下四个contstants预定有效值:

LOW 当引脚为低电平时,触发中断
CHANGE 当引脚电平发生改变时,触发中断
RISING 当引脚由低电平变为高电平时,触发中断
FALLING 当引脚由高电平变为低电平时,触发中断.

当发生外部中断时,调用一个指定函数。当中断发生时,该函数会取代正在执行的程序。大多数的Arduino板有两个外部中断:0(数字引脚2)和1(数字引脚3)。

arduino Mege有四个外部中断:数字2(引脚21),3(20针),4(引脚19),5(引脚18)。

注意事项

当中断函数发生时,delya()和millis()的数值将不会继续变化。当中断发生时,串口收到的数据可能会丢失。你应该声明一个变量来在未发生中断时储存变量。

重新分配中断
中断可以再任何时候通过attachInterrupt()命令进行改变。当重新使用attachInterrupt()时,先前分配的中断就会从对应引脚上移除。

启用\停止中断
Arduino也可以忽略所有中断。如果你需要在一段代码中不执行中断,只需要执行 noInterrupts()命令。当这段代码执行完以后,你可以使用 interrupts()命令重新启用中断。

删除中断
终端也可以通过detachInterrupt(interrupt_number)命令进行删除。


同样的电路不变,如果我们不是用中断会是什么样的效果呢?我们把下面的代码下载进入后和前面的效果进行对比。

int pbIn = 2;          // 定义输入信号引脚
int ledOut = 12;      // 定义输出指示灯引脚
int state = LOW;       // 定义默认输入状态

void setup()
{               
// 设置输入信号引脚为输入状态、输出引脚为输出状态
pinMode(pbIn, INPUT);
pinMode(ledOut, OUTPUT);
}

void loop()                     
{
state = digitalRead(pbIn);      //读取微动开关状态

digitalWrite(ledOut, state);    //把读取的状态赋予LED指示灯

//模拟一个长的流程或者复杂的任务
for (int i = 0; i < 100; i++)
{
    //延时10毫秒
    delay(10);
}
}

541板哥 发表于 2014-11-3 00:17:01

很详细,给赞了。不过我用promini实验却没成功,不知道问题在哪,用的是数字3管脚。郁闷中

弘毅 发表于 2014-11-4 08:29:04

541板哥 发表于 2014-11-3 00:17 static/image/common/back.gif
很详细,给赞了。不过我用promini实验却没成功,不知道问题在哪,用的是数字3管脚。郁闷中

这个。。。貌似没道理ing

mlyl 发表于 2017-2-22 12:56:53

开门,送快递的来了。

mlyl 发表于 2017-2-22 12:57:41

:):):):):):)
页: [1]
查看完整版本: OCROBOT入门教程022--外部中断的使用