“AttachInterrupt()”的版本间的差异
(未显示1个用户的1个中间版本) | |||
第32行: | 第32行: | ||
|} | |} | ||
<br> | <br> | ||
+ | |||
+ | |||
+ | <font color="red" size="">'''注意'''</font>:在附加函数中,delay()将不起作用,并且由millis()返回的值不会递增。 在功能中接收的串行数据可能会丢失。 你应该声明一个变量在未发生中断时储存变量。 有关详细信息,请参阅下面的ISR部分。 | ||
+ | |||
+ | |||
+ | <font color="orange" size="+1">'''使用中断'''</font> | ||
+ | |||
+ | 中断对于在微控制器程序中自动执行事件非常有用,并且可以帮助解决计时问题。 使用中断的良好任务可能包括读取旋转编码器或监视用户输入。 | ||
+ | |||
+ | 如果你想确保一个程序总是从旋转编码器捕获脉冲,这样就不会错过脉冲,所以编写一个程序来做任何其他事情会变得非常棘手,因为程序需要不断地轮询传感器 用于编码器的线,以便在发生时捕获脉冲。 其他传感器也具有类似的界面动态,例如尝试读取试图抓住咔嗒声的声音传感器,或者试图抓住硬币丢失的红外线槽传感器(光电断路器)。 在所有这些情况下,使用中断可以释放微控制器以完成其他工作,而不会丢失输入。 | ||
+ | |||
+ | |||
+ | <font color="orange" size="+1">'''关于中断服务程序'''</font> | ||
+ | |||
+ | ISR是特殊的功能,它们具有大多数其他功能没有的独特的限制。 ISR不能有任何参数,它们不应该返回任何东西。 | ||
+ | |||
+ | 一般来说,ISR应尽可能短且快。 如果您的草图使用多个ISR,则一次只能运行一次,其他中断将在当前操作完成后依照其所拥有的优先级执行。 millis()依赖于中断计数,所以它不会在ISR内增加。 由于delay()要求中断工作,所以如果在ISR内部调用,它将不起作用。 micros()最初工作,但会在1-2毫秒后开始行为不规律。 delayMicroseconds()不使用任何计数器,因此它将正常工作。 | ||
+ | |||
+ | 通常,全局变量用于在ISR和主程序之间传递数据。 为了确保ISR和主程序之间共享的变量被正确更新,请将其声明为 ''volatile''。 | ||
+ | |||
+ | 有关中断的更多信息,请参阅[http://gammon.com.au/interrupts Nick Gammon的笔记]。 | ||
第37行: | 第58行: | ||
<pre style="color:dimgray"> | <pre style="color:dimgray"> | ||
+ | |||
+ | attachInterrupt(digitalPinToInterrupt(pin), ISR, mode); (recommended) | ||
+ | attachInterrupt(interrupt, ISR, mode); (not recommended) | ||
+ | attachInterrupt(pin, ISR, mode) ; (not recommended Arduino Due, Zero, MKR1000, 101 only) | ||
</pre> | </pre> | ||
第43行: | 第68行: | ||
<font color="orange" size="+1">'''参数'''</font> | <font color="orange" size="+1">'''参数'''</font> | ||
− | + | * interrupt: the number of the interrupt (int) | |
+ | * pin: the pin number (Arduino Due, Zero, MKR1000 only) | ||
+ | * ISR: the ISR to call when the interrupt occurs; this function must take no parameters and return nothing. This function is sometimes referred to as an interrupt service routine. | ||
+ | * mode: defines when the interrupt should be triggered. Four constants are predefined as valid values: | ||
+ | :- LOW to trigger the interrupt whenever the pin is low, | ||
+ | :- CHANGE to trigger the interrupt whenever the pin changes value | ||
+ | :- RISING to trigger when the pin goes from low to high, | ||
+ | :- FALLING for when the pin goes from high to low. | ||
+ | :The Due board allows also: | ||
+ | :- HIGH to trigger the interrupt whenever the pin is high. | ||
<font color="orange" size="+1">'''返回'''</font> | <font color="orange" size="+1">'''返回'''</font> | ||
+ | none | ||
+ | |||
+ | |||
+ | <font color="orange" size="+1">'''示例'''</font> | ||
+ | |||
+ | <pre style="color:dimgray"> | ||
+ | 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; | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | |||
+ | <font color="orange" size="+1">'''中断引脚'''</font> | ||
+ | |||
+ | 通常您应该使用digitalPinToInterrupt(pin),而不是将中断号码直接放入草图中。 具有中断的特定引脚及其对中断号的映射在每种类型的板上都不同。 直接使用中断号码可能看起来很简单,但是当您的草图在不同的电路板上运行时,可能会导致兼容性问题。 | ||
+ | |||
+ | 然而,较老的草图通常具有直接的中断号码。 通常使用数字0(对于数字引脚2)或数字1(对于数字引脚3)。 下表显示了各种电路板上可用的中断引脚。 | ||
+ | |||
+ | 请注意,在下表中,中断号码是指传递给attachInterrupt()的号码。 由于历史原因,该编号并不总是直接对应于atmega芯片上的中断编号(例如,int.0对应于Atmega2560芯片上的INT4)。 | ||
+ | {|border="1" cellspacing="0" align="center" cellpadding="5" width="700px" | ||
+ | |- | ||
+ | |align="left"|'''Board''' | ||
+ | |align="left"|'''int.0''' | ||
+ | |align="left"|'''int.1''' | ||
+ | |align="left"|'''int.2''' | ||
+ | |align="left"|'''int.3''' | ||
+ | |align="left"|'''int.4''' | ||
+ | |align="left"|'''int.5''' | ||
+ | |- | ||
+ | |align="left"|Uno, Ethernet | ||
+ | |align="left"|2 | ||
+ | |align="left"|3 | ||
+ | |align="left"| | ||
+ | |align="left"| | ||
+ | |align="left"| | ||
+ | |align="left"| | ||
+ | |- | ||
+ | |align="left"|Mega2560 | ||
+ | |align="left"|2 | ||
+ | |align="left"|3 | ||
+ | |align="left"|21 | ||
+ | |align="left"|20 | ||
+ | |align="left"|19 | ||
+ | |align="left"|18 | ||
+ | |- | ||
+ | |align="left"|32u4-based (e.g Leonardo, Micro) | ||
+ | |align="left"|3 | ||
+ | |align="left"|2 | ||
+ | |align="left"|0 | ||
+ | |align="left"|1 | ||
+ | |align="left"|7 | ||
+ | |align="left"| | ||
+ | |- | ||
+ | |align="left"|Due, Zero, MKR1000, 101 | ||
+ | |colspan="6" align="left"|interrupt number = pin number | ||
+ | |} | ||
+ | <br> | ||
<font color="orange" size="+1">'''扩展阅读'''</font> | <font color="orange" size="+1">'''扩展阅读'''</font> | ||
− | :- [[ | + | :- [[detachInterrupt()]] |
2017年9月13日 (三) 14:59的最后版本
描述
Digital Pins With Interrupts
attachInterrupt的第一个参数是中断号。 通常,您应该使用digitalPinToInterrupt(引脚)将实际的数字引脚转换为特定的中断号。 例如,如果连接到引脚3,则使用digitalPinToInterrupt(3)作为attachInterrupt的第一个参数。
Board | Digital Pins Usable For Interrupts |
Uno, Nano, Mini, other 328-based | 2, 3 |
Mega, Mega2560, MegaADK | 2, 3, 18, 19, 20, 21 |
Micro, Leonardo, other 32u4-based | 0, 1, 2, 3, 7 |
Zero | all digital pins, except 4 |
MKR1000 Rev.1 | 0, 1, 4, 5, 6, 7, 8, 9, A1, A2 |
Due | all digital pins |
101 | all digital pins (Only pins 2, 5, 7, 8, 10, 11, 12, 13 work with CHANGE |
注意:在附加函数中,delay()将不起作用,并且由millis()返回的值不会递增。 在功能中接收的串行数据可能会丢失。 你应该声明一个变量在未发生中断时储存变量。 有关详细信息,请参阅下面的ISR部分。
使用中断
中断对于在微控制器程序中自动执行事件非常有用,并且可以帮助解决计时问题。 使用中断的良好任务可能包括读取旋转编码器或监视用户输入。
如果你想确保一个程序总是从旋转编码器捕获脉冲,这样就不会错过脉冲,所以编写一个程序来做任何其他事情会变得非常棘手,因为程序需要不断地轮询传感器 用于编码器的线,以便在发生时捕获脉冲。 其他传感器也具有类似的界面动态,例如尝试读取试图抓住咔嗒声的声音传感器,或者试图抓住硬币丢失的红外线槽传感器(光电断路器)。 在所有这些情况下,使用中断可以释放微控制器以完成其他工作,而不会丢失输入。
关于中断服务程序
ISR是特殊的功能,它们具有大多数其他功能没有的独特的限制。 ISR不能有任何参数,它们不应该返回任何东西。
一般来说,ISR应尽可能短且快。 如果您的草图使用多个ISR,则一次只能运行一次,其他中断将在当前操作完成后依照其所拥有的优先级执行。 millis()依赖于中断计数,所以它不会在ISR内增加。 由于delay()要求中断工作,所以如果在ISR内部调用,它将不起作用。 micros()最初工作,但会在1-2毫秒后开始行为不规律。 delayMicroseconds()不使用任何计数器,因此它将正常工作。
通常,全局变量用于在ISR和主程序之间传递数据。 为了确保ISR和主程序之间共享的变量被正确更新,请将其声明为 volatile。
有关中断的更多信息,请参阅Nick Gammon的笔记。
语法
attachInterrupt(digitalPinToInterrupt(pin), ISR, mode); (recommended) attachInterrupt(interrupt, ISR, mode); (not recommended) attachInterrupt(pin, ISR, mode) ; (not recommended Arduino Due, Zero, MKR1000, 101 only)
参数
- interrupt: the number of the interrupt (int)
- pin: the pin number (Arduino Due, Zero, MKR1000 only)
- ISR: the ISR to call when the interrupt occurs; this function must take no parameters and return nothing. This function is sometimes referred to as an interrupt service routine.
- mode: defines when the interrupt should be triggered. Four constants are predefined as valid values:
- - LOW to trigger the interrupt whenever the pin is low,
- - CHANGE to trigger the interrupt whenever the pin changes value
- - RISING to trigger when the pin goes from low to high,
- - FALLING for when the pin goes from high to low.
- The Due board allows also:
- - HIGH to trigger the interrupt whenever the pin is high.
返回
none
示例
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; }
中断引脚
通常您应该使用digitalPinToInterrupt(pin),而不是将中断号码直接放入草图中。 具有中断的特定引脚及其对中断号的映射在每种类型的板上都不同。 直接使用中断号码可能看起来很简单,但是当您的草图在不同的电路板上运行时,可能会导致兼容性问题。
然而,较老的草图通常具有直接的中断号码。 通常使用数字0(对于数字引脚2)或数字1(对于数字引脚3)。 下表显示了各种电路板上可用的中断引脚。
请注意,在下表中,中断号码是指传递给attachInterrupt()的号码。 由于历史原因,该编号并不总是直接对应于atmega芯片上的中断编号(例如,int.0对应于Atmega2560芯片上的INT4)。
Board | int.0 | int.1 | int.2 | int.3 | int.4 | int.5 |
Uno, Ethernet | 2 | 3 | ||||
Mega2560 | 2 | 3 | 21 | 20 | 19 | 18 |
32u4-based (e.g Leonardo, Micro) | 3 | 2 | 0 | 1 | 7 | |
Due, Zero, MKR1000, 101 | interrupt number = pin number |
扩展阅读
更多建议和问题欢迎反馈至 YFRobot论坛