Arduino UNO R3自学笔记18 之 Arduino的外部中断、定时中断介绍及应用
注意:学习和写作过程中,部分资料搜集于互联网,如有侵权请联系删除。
前言:上篇写了为啥要用中断,这篇具体展开写Arduino中断相关的知识。
温习:单片机在执行程序时,发生一些其它紧急的事情,单片机将立即暂停当前程序,赶去处理中断程序,处理完中断程序后再返回刚才暂停处接着执行原来的程序。这个过程称之为中断。
举个通俗易懂的例子:当你在看电视的时候,突然电话响了,你去接电话。接完电话回来继续看电视,这就是一个中断过程。我们以此为例分析一下:
主进程:看电视;
中断触发源:电话响了;
中断服务子程序:接电话;
通过上述例子我们了解了一些术语,以及中断这个过程。
1.Arduino中断分类
总体来讲,根据触发源的不同,中断分为外部中断和定时中断。
外部中断:一般是单片机硬件IO产生,比如外接的按钮、编码器。键盘等输入设备。
定时中断:一般是定时器产生的中断,周期性发生的事情。
2.Arduino的外部中断
Arduino UNO R3并不是所有的引脚支持外部中断,只有特定的几个引脚支持,下面列出了具体情况。
Arduino板子型号 | INT0 | INT1 | INT2 | INT3 | INT4 | INT5 |
UNO | 2 | 3 | / | / | / | / |
MEGA | 2 | 3 | 21 | 20 | 19 | 18 |
需要注意的是INT0到INT5指的是其中断编号。
知道了产生中断的引脚,那怎么触发中断的呢?
Arduino 上支持下表中的四种中断触发方式:
模式名称 | 说明 |
LOW | 电平触发,低电平触发。 |
CHANGE | 电平变化触发,即由高变低、由低变高均可触发。 |
RISING | 上升沿触发,即低电平变高电平触发。 |
FALLING | 下降沿触发,即高电平变低电平触发。 |
有了前面的基础知识。我们就可以初始化配置中断了,首先,给出初始化配置函数,如下:
attachInterrupt( interrupt,function,mode)
功能:对中断引脚进行初始化配置。
参数:
● interrupt,中断编号,注意,这里的中断编号并不是引脚编号。
● function,中断服务子程序,当中断被触发后即会运行此函数名称所代表的中断服务子程序。
● mode,中断模式。
注意以下内容:
使用 attachInterrupt 函数时注意:
● 在中断函数中 delay 函数不能使用。
● 使用 millis 函数始终返回进入中断前的值。
● 读取串口数据的话,可能会丢失。
● 中断函数中使用的变量需要定义为 volatile 型。
detachInterrupt( interrupt)
功能:禁用外部中断。
参数:
interrupt,需要禁用的中断编号。
interrupts()和nolnterrupts()
interrupts 和 noInterrupts 函数在 Arduino 中负责打开和关闭总中断,函数无返回值,无参数。
以上简单介绍了中断的大多数知识。
3.Arduino的外部中断使用方法
对于Arduino使用外部中断一般相对比较容易,具体步骤如下:
在编程前确认以下内容:
确定需求,比如要用中断检测按钮按下,根据需求选择好外部中断的引脚、触发方式 ,比如选择2号引脚,上升沿触发。
编程步骤:
(1) 在setup函数第一句使用noInterrupts 函数关闭总中断;
void setup()
{
noInterrupts();//关所有中断,防止在初始化时被中断
}
void loop()
{
}
(2) 初始化外部中断attachInterrupt( 0,function,RISING);
void setup()
{
noInterrupts();//关所有中断,防止在初始化时被中断
attachInterrupt( 0,function,RISING);//设置2号引脚上升沿触发,触发后执行function函数
}
void loop()
{
}
(3) 在setup函数最后一句使用Interrupts 函数打开总中断;
void setup()
{
noInterrupts();//关所有中断,防止在初始化时被中断
attachInterrupt( 0,function,RISING);//设置2号引脚上升沿触发,触发后执行function函数
Interrupts();//开所有中断,准备进入程序运行模式
}
void loop()
{
}
(4) 声明并编写中断服务子程序
void function();//声明函数,防止编译器报错
void setup()
{
noInterrupts();
attachInterrupt( 0,function,RISING);
Interrupts();
}
void loop()
{
}
void function()//中断服务子程序
{
//此处执行你要干的事
}
这样程序框架就完成了,接下来将中断服务子程序函数补全即可。
4.Arduino的定时中断
在 Arduino Uno 中有三个定时器,他们分别被使用到以下官方函数和库中:
- Timer0(8 位定时器)
- delay()
- delayMicroseconds()
- millis()
- micros()
- Timer1(16 位定时器)
- 伺服电机库 Servo.h
- Timer2(8 位定时器)
- tone()函数
各个定时器与引脚功能、软件库功能对应关系:
Timer0:D5/D6的PWM输出、delay()、millis()、delayMicroseconds()。
Timer1:D9/D10的PWM输出、舵机库Servo.h、TimerOne库。
Timer2:D3/D11的PWM输出、无源蜂鸣器的tone()、 MsTimer2库(三方库)。定时中断这部分内容,主要推荐使用MsTimer2第三方库,使用起来方便快捷,相关使用请看前面我写的这篇文章:
Arduino UNO R3自学笔记16 之 Arduino的定时器介绍及应用
5.总结
中断的使用和内容不止只有上述列出的,其它用法我们后续在具体案例中应用时再讲,同时也应该多多练习使用,推荐以下文章多多阅读学习。
关于此部分内容,可以阅读以下内容:
官方教程:https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/
定时器和中断:https://www.robotshop.com/community/forum/t/arduino-101-timers-and-interrupts/13072
Arduino定时器和中断的使用:https://www.pipipi.net/1030.html
Timer2库文件:https://playground.arduino.cc/Main/FlexiTimer2/
上一篇:Arduino UNO R3自学笔记17 之 Arduino为啥要用中断?
下一篇: