Arduino开发实例Arduino中断详解
Arduino开发实例-Arduino中断详解
Arduino中断详解
文章目录
本文是关于Arduino中断的文章。中断是一种让Arduino在特定事件发生时执行特定代码的功能。中断可以让Arduino在后台执行一些重要的任务,也可以让Arduino在低功耗模式下被唤醒。中断的使用需要注意一些细节和注意事项,本文将介绍中断的基本概念、使用方法和示例。
1、什么是中断?
中断是一种让Arduino在特定事件发生时暂停当前的程序,跳转到另一个预定义的函数(称为中断服务程序或ISR),执行完该函数后再返回原来的程序继续执行的功能。这种功能可以让Arduino在不影响主程序的情况下,及时响应一些外部或内部的信号,比如按钮按下、传感器触发、定时器溢出等。
2、如何使用中断?
要使用中断,首先需要确定哪些引脚可以作为中断源,即哪些引脚可以检测到电平变化或边沿变化,并触发中断。不同型号的Arduino有不同数量和位置的中断源引脚,通常用INTx来表示,其中x是一个数字。例如,Arduino Uno有两个中断源引脚,分别是INT0(对应数字引脚2)和INT1(对应数字引脚3)。Arduino Mega有六个中断源引脚,分别是INT0(对应数字引脚2)、INT1(对应数字引脚3)、INT2(对应数字引脚21)、INT3(对应数字引脚20)、INT4(对应数字引脚19)和INT5(对应数字引脚18)。具体的中断源引脚可以参考各型号Arduino的官方文档或数据手册。
其次,需要确定中断触发模式,即当中断源引脚上出现什么样的电平变化或边沿变化时,才会触发中断。Arduino支持四种中断触发模式,分别是:
- LOW:当中断源引脚上出现低电平时触发
- CHANGE:当中断源引脚上出现任何电平变化时触发
- RISING:当中断源引脚上出现上升沿(从低电平变为高电平)时触发
- FALLING:当中断源引脚上出现下降沿(从高电平变为低电平)时触发
不同的应用场景可能需要不同的中断触发模式,例如,如果要检测一个按钮是否被按下,可以使用CHANGE模式;如果要检测一个传感器是否输出了高电平信号,可以使用RISING模式;如果要检测一个定时器是否溢出了,可以使用FALLING模式等。
再次,需要定义一个ISR函数,即当中断被触发时要执行的代码。ISR函数必须符合以下要求:
- ISR函数必须没有参数和返回值
- ISR函数必须尽可能简短和快速
- ISR函数不能使用延时函数或者阻塞函数
- ISR函数不能调用其他ISR函数或者被其他ISR函数调用
- ISR函数不能使用浮点数或者字符串等复杂数据类型
- ISR函数不能修改或者依赖于主程序中被修改的变量,除非该变量被声明为volatile
最后,需要在setup()函数中使用attachInterrupt()函数来注册ISR函数,并指定要监听的中断源和触发模式。attachInterrupt()函数有三个参数:
interrupt:要监听的中断源编号,可以直接用INTx表示,也可以用digitalPinToInterrupt(pin)函数将数字引脚转
换成中断源编号。例如,如果要监听数字引脚2上的中断,可以用INT0或者digitalPinToInterrupt(2)表示。
- mode:要监听的中断触发模式,可以用LOW、CHANGE、RISING或者FALLING表示。
- ISR:要注册的ISR函数的名称,不需要加括号。例如,如果要监听数字引脚2上的中断,当该引脚上出现上升沿时,执行名为blink的ISR函数,可以在setup()函数中写如下代码:
1 | attachInterrupt(digitalPinToInterrupt(2), blink, RISING); |
或者
1 | attachInterrupt(INT0, blink, RISING); |
其中,blink是一个自定义的ISR函数,可以在setup()函数之前或之后定义,例如:
1 | void blink() { |
复制
注意,当使用attachInterrupt()函数注册ISR函数时,Arduino会自动将对应的中断源引脚设置为输入模式,并启用内部上拉电阻。如果不想使用内部上拉电阻,可以在setup()函数中使用pinMode()函数将中断源引脚设置为输入模式,并使用外部下拉电阻。
另外,如果不想再监听某个中断源引脚上的中断,可以在loop()函数中或者其他地方使用detachInterrupt()函数来取消注册ISR函数。detachInterrupt()函数只有一个参数:
+ interrupt:要取消监听的中断源编号,可以直接用INTx表示,也可以用digitalPinToInterrupt(pin)函数将数字引脚转换成中断源编号。例如,如果要取消监听数字引脚2上的中断,可以在loop()函数中或者其他地方写如下代码:
1 | detachInterrupt(digitalPinToInterrupt(2)); |
或者
1 | detachInterrupt(INT0); |
3、中断的示例
下面给出一些使用中断的示例,以供参考。
3.1 ### 示例一:检测按钮按下
这个示例演示了如何使用中断来检测一个按钮是否被按下,并在串口监视器上打印出按下次数。假设按钮连接在数字引脚2和GND之间,当按钮按下时,数字引脚2会变为低电平。因此,我们可以使用CHANGE模式来监听数字引脚2上的电平变化,并在ISR函数中增加一个计数变量。代码如下:
1 | volatile int count = 0; //定义一个计数变量,并声明为volatile |
运行这个程序后,在串口监视器上可以看到每次按下按钮时,计数变量的值会增加一。
3.2示例二:控制LED闪烁
这个示例演示了如何使用中断来控制一个LED的闪烁频率。假设LED连接在数字引脚13和GND之间,我们可以使用定时器溢出产生的中断来切换LED的状态。Arduino Uno有三个定时器(Timer0、Timer1和Timer2),每个定时器都有自己的寄存器和控制位。这里我们使用Timer1作为例子。Timer1是一个16位定时器,它有两个比较匹配寄存器(OCR1A和OCR1B),分别对应两个比这个示例演示了如何使用中断来控制一个LED的闪烁频率。假设LED连接在数字引脚13和GND之间,我们可以使用定时器溢出产生的中断来切换LED的状态。Arduino Uno有三个定时器(Timer0、Timer1和Timer2),每个定时器都有自己的寄存器和控制位。这里我们使用Timer1作为例子。Timer1是一个16位定时器,它有两个比较匹配寄存器(OCR1A和OCR1B),分别对应两个比较匹配中断(TIMER1_COMPA_vect和TIMER1_COMPB_vect)。我们可以通过设置这些寄存器和控制位,来调节定时器的工作模式、预分频系数、比较匹配值等,从而改变中断的触发频率。代码如下:
1 | volatile bool ledState = false; //定义一个LED状态变量,并声明为volatile |
运行这个程序后,可以看到数字引脚13上的LED每秒闪烁一次。如果想要改变闪烁频率,可以修改OCR1A的值,或者修改TCCR1B中的预分频系数。例如,如果想要让LED每半秒闪烁一次,可以将OCR1A设置为15625;如果想要让LED每两秒闪烁一次,可以将TCCR1B中的预分频系数设置为1024(即将CS12和CS10都置为1)。具体的计算方法可以参考Arduino官方文档或数据手册。
3.3示例三:测量脉冲宽度
这个示例演示了如何使用中断来测量一个脉冲信号的宽度。假设脉冲信号输入到数字引脚2上,我们可以使用RISING和FALLING模式来监听该引脚上的边沿变化,并在ISR函数中记录时间戳。代码如下:
1 | volatile unsigned long startTime = 0; //定义一个开始时间变量,并声明为volatile |
运行这个程序后,在串口监视器上可以看到每秒打印出一次脉冲宽度的值,单位为微秒。如果想要改变测量的精度,可以修改delay()函数的参数,或者使用其他的时间函数,比如millis()或者micros()。具体的使用方法可以参考Arduino官方文档或数据手册。
4、中断的注意事项
使用中断时,需要注意以下几点:
- 中断是一种高优先级的功能,当中断被触发时,Arduino会暂停当前的程序,跳转到ISR函数,并在执行完ISR函数后再返回原来的程序继续执行。这意味着,在ISR函数执行期间,主程序和其他中断都会被阻塞,无法响应其他事件。因此,ISR函数必须尽可能简短和快速,避免使用延时函数或者阻塞函数,以免影响主程序和其他中断的正常运行。
- 中断是一种不可预知的功能,当中断被触发时,Arduino会立即跳转到ISR函数,并在执行完ISR函数后再返回原来的程序继续执行。这意味着,在ISR函数执行期间,主程序中被修改的变量可能会出现不一致或者错误的情况。例如,如果主程序中有一个变量a,在某一时刻被赋值为10,在下一时刻被赋值为20,在这两个时刻之间,如果发生了中断,并且ISR函数中也使用了变量a,那么变量a的值可能会出现混乱。因此,ISR函数不能修改或者依赖于主程序中被修改的变量,除非该变量被声明为volatile。volatile是一种修饰符,它可以告诉编译器不要对该变量进行优化或者缓存,而是每次都从内存中读取或者写入该变量的值。这样可以保证该变量在主程序和ISR函数之间保持一致。
- 中断是一种有限制的功能,并不是所有的引脚都可以作为中断源,也不是所有的事件都可以作为中断触发模式。不同型号的Arduino有不同数量和位置的中断源引脚,通常用INTx来表示,其中x是一个数字。Arduino支持四种中断触发模式,分别是LOW、CHANGE、RISING和FALLING。具体的中断源引脚和触发模式可以参考各型号Arduino的官方文档或数据手册。
5、总结
本文介绍了中断的基本概念、使用方法和示例。中断是一种让Arduino在特定事件发生时执行特定代码的功能。中断可以让Arduino在后台执行一些重要的任务,也可以让Arduino在低功耗模式下被唤醒。中断的使用需要注意一些细节和注意事项,以保证
文章来源: https://iotsmart.blog.csdn.net/article/details/131268764
