attachInTerrupt()
有这个专业词要知道:
Digital Pins:电子引脚
ISRs(Interrupt Service Routines):中断服务程序
ISR(Interrupt Service Routine):中断服务程序
attachInTerrupt()第一个参数为中断的引脚号,一般使用digitalPinToInterrupt(pin)去设置。比如如果使用中断引脚3,首先使用digitalPinToInterrupt(3),然后将其传入attachInterrupt()
下面是各个板子对应的引脚号:
需要注意的地方:
在中断函数里面delay()函数是不会工作的,millis()返回值不会增加,串口接收的数据可能会丢失,如果在中断函数中要修改全局变量,需要把全局变量声明中添加volatile关键字。
使用中断的目的,就是为了更好的写程序。这样程序就不要用轮询,不停的问,而是中断一来就停止手上的工作,从而直接进行中断函数的响应。
关于中断服务程序(About Interrupt Service Routines)
ISR我个人觉得更正确的翻译为中断服务函数。ISR比较特殊,不能有参数和返回值,也不返回任何数据。
这里有几点要注意的:
如果同时有多个ISR被触发,只有一个ISP会被响应,这依赖于他们的优先级。delay()和millis()是不能用的,millis()他依赖于中断计时器(这里就和写C/C++的时候统计程序运行时间,在运行时间里面调用windows.h中的sleep,这个调用后连统计时间的函数都会被sleep掉)micros在前1-2ms是正常的,之后就不正常了。官方推荐在中断函数中使用delayMicroseconds()这个函数。
在ISR中一般使用全局变量进行操作,在全局变量中要添加volatile关键字。
这些函数都是异步的操作:
关于参数:
下面是官方给出的示例代码:
const byte ledPin = 13;
const byte interruptPin = 2;
volatile byte state = LOW;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);
}
void loop() {
digitalWrite(ledPin, state);
}
void blink() {
state = !state;
}