如果你熟悉WINDOWS中断(IRQ)那么这段理论介绍可以忽略。就像WINDOWS中断一样,Arduino也支持中断,主要包括外部中断、时钟中断,串口事件处理程序也可以被看作一种中断。
一、什么是硬件中断
举一个栗子,这天我们正在外面吃饭,手机响了拿出来一看是老妈的电话,于是出去接了个电话回来继续吃。这就是中断——正在做吃饭这件事情的时候被按下暂停键做了其他事情回来继续吃饭。电话打来这就是中断请求,打电话的过程就是处理中断请求的过程,在Arduino中这个过程不要太过耗时最好只处理一些简单的数据运算。
时钟中断也是类似的情况。但是,串口事件处理函数情况不同,它被夹在两次LOOP函数之间,而不像其他中断是在代码的任意位置被转移。
二、如何使用外部中断
attachInterrupt(0, InterruptProc, FALLING);
对于Uno r3来说:
参数1:0或1,表示D2或D3端口
参数2:中断过程中调用的函数
参数3:引发中断的模式
low 输入为低时
change 发生变化时
rising 由低变高时
falling 由高变低时
首先,我们需要注册外部中断,而后在中断处理函数中编写处理代码。常用的例子是使用按键时:
1、硬件连接:
将按键两端分别接D2和GND。代码中我们开启内部上拉电阻,此时当按键按下时触发低电平。
2、代码:
/*
Name: Sketch1.ino
Created: 2019/2/12 8:08:53
Author: Administrator
*/
int clickCount = 0;
uint8_t PinInterrupt = 2;
// the setup function runs once when you press reset or power the board
void setup() {
Serial.begin(115200); //打开串口
pinMode(PinInterrupt, INPUT_PULLUP); //设置D2引脚输入模式并打开内部上拉
attachInterrupt(PinInterrupt-2, InterruptProc, FALLING); //0表示D2引脚,由高变低时触发中断
}
// the loop function runs over and over again until power down or reset
void loop() {
Serial.println(clickCount);
delay(200);
}
void InterruptProc() {
clickCount++;
}
现在把代码烧录到Arduino uno r3,按下几次按键可以看到输出窗口中的输出值不断随着按键次数增加而增大:
同时,我们也发现了一个奇怪的问题:并不是按下一次按键数值就增加1,这是为什么呢?原因是按键抖动,所谓按键抖动是指按键按下时金属片相结合的过程中,并不是一次性就接触好了,断开时也是如此,所以会产生若干个信号,这些信号的持续时间非常短,但会被Arduino接收到。显然,这种抖动是有害的,我们想办法去除这种抖动,方法有很多,包括硬件去抖动的方式,因为这些抖动信号非常短暂,属于一种高频脉冲,所以我们可以并联一个电容使得这种高频信号被短路,也可以采用软件去抖动的方式,只要我们在代码中忽略短暂的时间内的信号就可以了。这里我采用了一个陶瓷电容进行硬件去抖动,得到了如下的结果:
可以看到有明显的效果但由于电容大小不匹配,还有抖动发生。所以无论是硬件去抖动还是软件去抖动,都需要匹配合适的电容或者延时时间才能达到满意的效果。