极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 257176|回复: 77

Arduino入门教程--第十九课--Arduino中断的使用

  [复制链接]
发表于 2012-9-21 18:48:31 | 显示全部楼层 |阅读模式
中断的基本原理

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

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

什么是中断?

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

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

使用中断的好处

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

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

进入正题

我们在本次试验中使用ocrobot mango(Arduino UNO兼容板),IDE使用1.0.1版本。

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




标准的数字输入与输出--没有中断

如果你按照上面的电路图进行了接线,把下面的代码编译上传进入Arduino。

代码用来读取你输入的值,然后作为条件进行比较,


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

  4. void setup()
  5. {               
  6.   // 设置输入信号引脚为输入状态、输出引脚为输出状态
  7.   pinMode(pbIn, INPUT);
  8.   pinMode(ledOut, OUTPUT);
  9. }

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

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

  14.   //模拟一个长的流程或者复杂的任务
  15.   for (int i = 0; i < 100; i++)
  16.   {
  17.     //延时10毫秒
  18.     delay(10);
  19.   }
  20. }
复制代码


下面视频是该代码的实验效果,按下开关,LED状态不会立刻改变,要按住一会儿才能改变。



使用中断

现在,我们使用相同的电路连接图,然后修改代码以使用硬件中断。然后把下面的代码下载进入控制板中,当按下按钮时,LED的状态就会立刻改变,尽管代码仍然是在主循环中,而且是同样的延时。


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

  4. void setup()
  5. {               
  6.   // 置ledOut引脚为输出状态
  7.   pinMode(ledOut, OUTPUT);

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

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

  20. void stateChange()
  21. {
  22.   state = !state;
  23.   digitalWrite(ledOut, state);  
  24. }
复制代码


下面视频是该代码的实验效果,按下开关,LED状态就会立刻变化。



中断命令语法介绍

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)命令进行删除。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2012-10-29 13:00:27 | 显示全部楼层
ttyp 发表于 2012-10-29 12:17
谢谢您的回答,不过我还是有几个问题

1.抖动是仅仅按钮才有的吧,比如用闸刀开关会有抖动么?


额。。。闸刀开关在接触的那一瞬间,应该也是有抖动的。。不过闸刀一般是大功率地方用吧。。那点抖动可以忽略不计了,对于那种场合来说。

硬件消抖,软件消抖,可以参考这篇帖子。
http://www.geek-workshop.com/thread-74-1-1.html
回复 支持 1 反对 0

使用道具 举报

发表于 2012-10-28 21:25:55 | 显示全部楼层
图中不同颜色的连线是怎么来的.

为什么我的 Fritzing ,就只能有绿色连线一种呢.

回复 支持 反对

使用道具 举报

发表于 2012-10-28 21:28:39 | 显示全部楼层
tom 发表于 2012-10-28 21:25
图中不同颜色的连线是怎么来的.

为什么我的 Fritzing ,就只能有绿色连线一种呢.

点击线后,在右下方的属性栏中,可以选择颜色。
回复 支持 反对

使用道具 举报

发表于 2012-10-29 10:05:31 | 显示全部楼层
问一个问题,LZ演示的效果中不能明显的控制LED一开一关的效果,这个是按钮的原因(抖动)?还是其他什么原因啊?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-10-29 10:14:35 | 显示全部楼层
ttyp 发表于 2012-10-29 10:05
问一个问题,LZ演示的效果中不能明显的控制LED一开一关的效果,这个是按钮的原因(抖动)?还是其他什么原因 ...

响应速度
回复 支持 反对

使用道具 举报

发表于 2012-10-29 10:28:53 | 显示全部楼层
本帖最后由 ttyp 于 2012-10-29 10:32 编辑
迷你强 发表于 2012-10-29 10:14
响应速度


但是你绑定的是change事件啊,应该只会一开一关各改变一次吧,正确的是按下点亮,松开熄灭。 但是演示里有时松开灯还是亮的
回复 支持 反对

使用道具 举报

发表于 2012-10-29 11:33:37 | 显示全部楼层
ttyp 发表于 2012-10-29 10:28
但是你绑定的是change事件啊,应该只会一开一关各改变一次吧,正确的是按下点亮,松开熄灭。 但是演示里 ...

按键抖动,因为软硬件都没有做消抖,只是演示下使用中断和不使用中断的区别。做了消抖后就能准确的控制亮灭了。
回复 支持 反对

使用道具 举报

发表于 2012-10-29 12:17:12 | 显示全部楼层
弘毅 发表于 2012-10-29 11:33
按键抖动,因为软硬件都没有做消抖,只是演示下使用中断和不使用中断的区别。做了消抖后就能准确的控制亮 ...

谢谢您的回答,不过我还是有几个问题

1.抖动是仅仅按钮才有的吧,比如用闸刀开关会有抖动么?
2.硬件消抖有资料么?
3.软件消抖是使用延时么

按钮是我们经常要用的东西,但是却有一个这么大的问题,这让人在使用的时候莫名其妙!
回复 支持 反对

使用道具 举报

发表于 2012-12-7 10:25:54 | 显示全部楼层
学习了,今天又认识中断了,天天逛极客都有进步啊
回复 支持 反对

使用道具 举报

发表于 2012-12-14 20:04:22 | 显示全部楼层
{:soso_e113:}学习了
回复 支持 反对

使用道具 举报

发表于 2012-12-15 09:47:23 | 显示全部楼层
学习了。原来还有消抖
回复 支持 反对

使用道具 举报

发表于 2012-12-15 12:46:28 | 显示全部楼层
state = digitalRead(pbIn);      这段可以给state变量重新赋值 理解第一个事例,可第二个
state = !state;  digitalWrite(ledOut, state);   没发现哪里给变量赋值啊,请问这里是个什么原理,state = !state;难道是这里?这么也可以? 他是int类型 不能判断ture false啊     volatile int state = LOW;    和直接int 啥区别?  volatile有了他就可以true或false吗?对了,这里面 !叹号 是不是跟其他编程语言一样,跟true false 有关?
回复 支持 反对

使用道具 举报

发表于 2012-12-15 15:45:54 | 显示全部楼层
arduino下!用法可以参考语法手册
http://wiki.geek-workshop.com/do ... e_reference:boolean
回复 支持 反对

使用道具 举报

发表于 2013-2-20 18:44:29 | 显示全部楼层
弘毅 发表于 2012-10-29 13:00
额。。。闸刀开关在接触的那一瞬间,应该也是有抖动的。。不过闸刀一般是大功率地方用吧。。那点抖动可 ...

链接的帖子看了,受益匪浅,谢谢。
不过对于中断这个例子,如何进行相应的软件消抖呢?不知道在哪儿进行延时判断……
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-3-28 22:53 , Processed in 0.050279 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表