2019-2-18 14:57:12 [显示全部楼层]
8431浏览
查看: 8431|回复: 3

[入门] Arduino学习(七)中断

[复制链接]
一、中断(Interrupt)的基本概念

中断(Interrupt)是计算机的一个重要概念,现代计算机普遍采用中断技术。



什么是中断呢?

CPU执行时原本是按程序指令一条一条向下顺序执行的。 但如果此时发生了某一事件B请求CPU迅速去处理(中断发生),CPU暂时中断当前的工作,转去处理事件B(中断响应和中断服务).  待CPU将事件B处理完毕后, 再回到原来被中断的地方继续执行程序(中断返回),这一过程称为中断 。

打个比方:假如你正在读书,这时电话响了。你放下手中的书,去接电话。接完电话后,再继续回来读书,并从原来读的地方继续往下读。



当中断发生时,程序执行流程图示如下:

Arduino学习(七)中断图1

计算机为什么要采用中断?
为了说明这个问题,再举一例子。假设你有一个朋友来拜访你,但是由于不知道何时到达,你只能在大门等待,于是什么事情也干不了。如果在门口装一个门铃,你就不必在门口等待而去干其它的工作,朋友来了按门铃通知你,你这时才中断你的工作去开门,这样就避免等待和浪费时间。计算机也是一样,例如键盘输入,如果不采用中断技术,CPU将不断扫描键盘有否输入,经常处于等待状态,效率极低。而采用了中断方式,CPU可以进行其它的工作,只键盘有按键并发出中断请求时,才予以响应,暂时中断当前工作转去执行读取键盘按键,读完成后又返回执行原来的程序。这样就大大地提高了计算机系统的效率。



中断的种类和优先级

先看一个PC上的中断(如下图,在我的电脑属性-设备管理器-查看-依连接顺序排列资源,再展开中断请求)

Arduino学习(七)中断图2

可见,中断0是系统时钟,中断1是键盘,中断4是COM1 ...

中断号越低的优先级越高。

所谓优先级,就是当两个或多个中断请求同时发生时,CPU先响应优先级最高的中断



Arduino Nano 使用ATMega328芯片,支持几种中断: RESET中断、外部中断、时钟中断

RESET中断,就是当RESET管脚接低电平,则中止当前程序,重启CPU

时钟中断,是指设定CPU内部定时器后,当到达指定时间,将产生中断请求。常用于定时。

外部中断,就是当CPU的外部中断管脚电平变动时,将产生中断请求。 常用于键盘输入、串口通信等。

有两个管脚(D2, D3脚)支持外部中断。使用中断前,需先设置CPU为中断Enable状态。



二、Arduino的定时器中断

使用定时器中断前,必须先安装MsTimer2库,并在程序中引用头文件 MsTimer2.h中。使用例程如下:

[mw_shl_code=applescript,true]#include <MsTimer2.h>     //定时器库的头文件



int tick = 0; //计数值



//中断服务程序

void onTimer()

{

  Serial.print("timer ");

  Serial.println(tick++);

}



void setup()

{

  Serial.begin(9600); //初始化串口

  

  MsTimer2::set(1000, onTimer); //设置中断,每1000ms进入一次中断服务程序 onTimer()

  MsTimer2::start(); //开始计时

}



void loop()

{

  

}[/mw_shl_code]


程序运行效果:
每隔1000毫秒,产生一次时钟中断,并进入中断服务程序 onTimer(), 向串口打印一串文字。

在Arduino IDE中打开串口监视窗口,可见打印的文字

timer 0

timer 1

timer 2

...



如果编译过程出现错误“error: 'MsTimer2' has not been declared”,多半是因为MsTimers库未安装。

MsTimer2库的安装方法:

1, 新建一个目录名为 MsTimer2,  在 https://github.com/PaulStoffregen/MsTimer2 下载全部文件, 存入目录中。

2, 在Arduino IDE中,点菜单“Sketch -- Import Liberary -- Add Liberary”,选择MsTimer2目录后,点确定





三、Arduino的外部中断

我们把一个按键开关,接在数字管脚上,触发外部中断事件。

不是所有数字管脚都支持外部中断,对于Arduino NANO,  D2, D3两个脚支持外部中断。


1, 准备元器件和器材

     按键开关  一个

     面包板一块

     1K 电阻一个

      杜邦线若干


2 电路原理图

Arduino学习(七)中断图3

图中:  开关接在5V与GND之间,串接一个电阻R作为限流电阻。D2接到开关上。

当开关闭合, D2的电平为0V(低电平),  当中断有效时,将触发外部中断。



3,用面包板接线

把开关, 电阻插入面包板, 按上述电路原理图,用杜邦线接好线



4, 在Arduino IDE中写个Arduino程序

[mw_shl_code=applescript,true]int pinInterrupt = 2; //接中断信号的脚



void onChange()

{

   if ( digitalRead(pinInterrupt) == LOW )

      Serial.println("Key Down");

   else

      Serial.println("Key UP");

}



void setup()

{

   Serial.begin(9600); //打开串口



   pinMode( pinInterrupt, INPUT);//设置管脚为输入

   

   //Enable中断管脚, 中断服务程序为onChange(), 监视引脚变化

   attachInterrupt( digitalPinToInterrupt(pinInterrupt), onChange, CHANGE);

}



void loop()

{

  // 模拟长时间运行的进程或复杂的任务。

  for (int i = 0; i < 100; i++)

  {

    // 什么都不做,等待10毫秒

    delay(10);

  }

}[/mw_shl_code]


运行效果: 在Arduino IDE中打开串口监视窗口,可见打印的文字

当按键按下,进入中断服务程序,打印  "Key Down"
当按键抬起,进入中断服务程序,打印  "Key Up"



上述程序如果在Arduino 1.0版本编译时,出现错误“NOT_AN_INTERRUPT' was not declared”,则在程序最开始处加一句

#define NOT_AN_INTERRUPT -1



附:attachInterrupt()函数的语法介绍
attachInterrupt( digitalPinToInterrupt(pin) , function, mode)

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

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


一、中断(Interrupt)的基本概念

中断(Interrupt)是计算机的一个重要概念,现代计算机普遍采用中断技术。



什么是中断呢?

CPU执行时原本是按程序指令一条一条向下顺序执行的。 但如果此时发生了某一事件B请求CPU迅速去处理(中断发生),CPU暂时中断当前的工作,转去处理事件B(中断响应和中断服务).  待CPU将事件B处理完毕后, 再回到原来被中断的地方继续执行程序(中断返回),这一过程称为中断 。

打个比方:假如你正在读书,这时电话响了。你放下手中的书,去接电话。接完电话后,再继续回来读书,并从原来读的地方继续往下读。



当中断发生时,程序执行流程图示如下:

Arduino学习(七)中断图4

计算机为什么要采用中断?
为了说明这个问题,再举一例子。假设你有一个朋友来拜访你,但是由于不知道何时到达,你只能在大门等待,于是什么事情也干不了。如果在门口装一个门铃,你就不必在门口等待而去干其它的工作,朋友来了按门铃通知你,你这时才中断你的工作去开门,这样就避免等待和浪费时间。计算机也是一样,例如键盘输入,如果不采用中断技术,CPU将不断扫描键盘有否输入,经常处于等待状态,效率极低。而采用了中断方式,CPU可以进行其它的工作,只键盘有按键并发出中断请求时,才予以响应,暂时中断当前工作转去执行读取键盘按键,读完成后又返回执行原来的程序。这样就大大地提高了计算机系统的效率。



中断的种类和优先级

先看一个PC上的中断(如下图,在我的电脑属性-设备管理器-查看-依连接顺序排列资源,再展开中断请求)

Arduino学习(七)中断图5

可见,中断0是系统时钟,中断1是键盘,中断4是COM1 ...

中断号越低的优先级越高。

所谓优先级,就是当两个或多个中断请求同时发生时,CPU先响应优先级最高的中断



Arduino Nano 使用ATMega328芯片,支持几种中断: RESET中断、外部中断、时钟中断

RESET中断,就是当RESET管脚接低电平,则中止当前程序,重启CPU

时钟中断,是指设定CPU内部定时器后,当到达指定时间,将产生中断请求。常用于定时。

外部中断,就是当CPU的外部中断管脚电平变动时,将产生中断请求。 常用于键盘输入、串口通信等。

有两个管脚(D2, D3脚)支持外部中断。使用中断前,需先设置CPU为中断Enable状态。



二、Arduino的定时器中断

使用定时器中断前,必须先安装MsTimer2库,并在程序中引用头文件 MsTimer2.h中。使用例程如下:

[mw_shl_code=applescript,true]#include <MsTimer2.h>     //定时器库的头文件



int tick = 0; //计数值



//中断服务程序

void onTimer()

{

  Serial.print("timer ");

  Serial.println(tick++);

}



void setup()

{

  Serial.begin(9600); //初始化串口

  

  MsTimer2::set(1000, onTimer); //设置中断,每1000ms进入一次中断服务程序 onTimer()

  MsTimer2::start(); //开始计时

}



void loop()

{

  

}[/mw_shl_code]


程序运行效果:
每隔1000毫秒,产生一次时钟中断,并进入中断服务程序 onTimer(), 向串口打印一串文字。

在Arduino IDE中打开串口监视窗口,可见打印的文字

timer 0

timer 1

timer 2

...



如果编译过程出现错误“error: 'MsTimer2' has not been declared”,多半是因为MsTimers库未安装。

MsTimer2库的安装方法:

1, 新建一个目录名为 MsTimer2,  在 https://github.com/PaulStoffregen/MsTimer2 下载全部文件, 存入目录中。

2, 在Arduino IDE中,点菜单“Sketch -- Import Liberary -- Add Liberary”,选择MsTimer2目录后,点确定





三、Arduino的外部中断

我们把一个按键开关,接在数字管脚上,触发外部中断事件。

不是所有数字管脚都支持外部中断,对于Arduino NANO,  D2, D3两个脚支持外部中断。


1, 准备元器件和器材

     按键开关  一个

     面包板一块

     1K 电阻一个

      杜邦线若干


2 电路原理图

Arduino学习(七)中断图6

图中:  开关接在5V与GND之间,串接一个电阻R作为限流电阻。D2接到开关上。

当开关闭合, D2的电平为0V(低电平),  当中断有效时,将触发外部中断。



3,用面包板接线

把开关, 电阻插入面包板, 按上述电路原理图,用杜邦线接好线



4, 在Arduino IDE中写个Arduino程序

[mw_shl_code=applescript,true]int pinInterrupt = 2; //接中断信号的脚



void onChange()

{

   if ( digitalRead(pinInterrupt) == LOW )

      Serial.println("Key Down");

   else

      Serial.println("Key UP");

}



void setup()

{

   Serial.begin(9600); //打开串口



   pinMode( pinInterrupt, INPUT);//设置管脚为输入

   

   //Enable中断管脚, 中断服务程序为onChange(), 监视引脚变化

   attachInterrupt( digitalPinToInterrupt(pinInterrupt), onChange, CHANGE);

}



void loop()

{

  // 模拟长时间运行的进程或复杂的任务。

  for (int i = 0; i < 100; i++)

  {

    // 什么都不做,等待10毫秒

    delay(10);

  }

}

[/mw_shl_code]

运行效果: 在Arduino IDE中打开串口监视窗口,可见打印的文字

当按键按下,进入中断服务程序,打印  "Key Down"
当按键抬起,进入中断服务程序,打印  "Key Up"



上述程序如果在Arduino 1.0版本编译时,出现错误“NOT_AN_INTERRUPT' was not declared”,则在程序最开始处加一句

#define NOT_AN_INTERRUPT -1



附:attachInterrupt()函数的语法介绍
attachInterrupt( digitalPinToInterrupt(pin) , function, mode)

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

LOW 当引脚为低电平时,触发中断
CHANGE 当引脚电平发生改变时,触发中断
RISING 当引脚由低电平变为高电平时,触发中断
FALLING 当引脚由高电平变为低电平时,触发中断
---------------------
作者:JoStudio
来源:CSDN
原文:https://blog.csdn.net/c80486/article/details/52622035

gada888  版主

发表于 2019-2-18 16:07:40

支持
回复

使用道具 举报

狂风飙升  初级技师

发表于 2020-2-2 16:30:14

能都上传一个类似的Mind+中的模块化例子,代码有点难懂
回复

使用道具 举报

txm派瑞深山锹  高级技师 来自手机

发表于 2020-3-7 23:22:58

tyjjr 发表于 2019-2-18 14:57
一、中断(Interrupt)的基本概念

中断(Interrupt)是计算机的一个重要概念,现代计算机普遍采用中断技术。 ...

终于学会中断了
回复

使用道具 举报

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

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail