中断 1 会中断中断 0,还是中断 1 会等到中断 0 的处理程序执行完毕?
除非您在 ISR(中断服务程序)中专门重新启用中断,否则在处理下一个中断之前,当前运行的任何中断都会完成,再加上一条机器代码指令。
大多数中断在处理器内部设置一个标志,在指令之间检查该标志,以查看是否应该处理中断。标志按优先级顺序检查。在 Uno 上是:
1 Reset
2 External Interrupt Request 0 (pin D2) (INT0_vect)
3 External Interrupt Request 1 (pin D3) (INT1_vect)
4 Pin Change Interrupt Request 0 (pins D8 to D13) (PCINT0_vect)
5 Pin Change Interrupt Request 1 (pins A0 to A5) (PCINT1_vect)
6 Pin Change Interrupt Request 2 (pins D0 to D7) (PCINT2_vect)
7 Watchdog Time-out Interrupt (WDT_vect)
8 Timer/Counter2 Compare Match A (TIMER2_COMPA_vect)
9 Timer/Counter2 Compare Match B (TIMER2_COMPB_vect)
10 Timer/Counter2 Overflow (TIMER2_OVF_vect)
11 Timer/Counter1 Capture Event (TIMER1_CAPT_vect)
12 Timer/Counter1 Compare Match A (TIMER1_COMPA_vect)
13 Timer/Counter1 Compare Match B (TIMER1_COMPB_vect)
14 Timer/Counter1 Overflow (TIMER1_OVF_vect)
15 Timer/Counter0 Compare Match A (TIMER0_COMPA_vect)
16 Timer/Counter0 Compare Match B (TIMER0_COMPB_vect)
17 Timer/Counter0 Overflow (TIMER0_OVF_vect)
18 SPI Serial Transfer Complete (SPI_STC_vect)
19 USART Rx Complete (USART_RX_vect)
20 USART, Data Register Empty (USART_UDRE_vect)
21 USART, Tx Complete (USART_TX_vect)
22 ADC Conversion Complete (ADC_vect)
23 EEPROM Ready (EE_READY_vect)
24 Analog Comparator (ANALOG_COMP_vect)
25 2-wire Serial Interface (I2C) (TWI_vect)
26 Store Program Memory Ready (SPM_READY_vect)
(请注意,重置不能被屏蔽)。
可以想象,一个低级中断可能正在进行中(例如 TIMER0_OVF_vect)。当它忙于做它的事情时,可能会发生多个其他中断事件(并在 CPU 中设置相应的位)。它们将按照上述顺序进行服务,而不是按照它们实际发生的时间顺序。
可以写入硬件寄存器以取消挂起的中断 - 即清除标志。
提到“多一条机器代码指令”的原因是处理器被设计为保证当它从未启用的中断转换到启用的中断时,总是执行多一条指令。
这使您可以编写如下代码:
interrupts (); // guarantees next instruction executed
sleep_cpu (); // sleep now
没有它,在进入睡眠之前可能会发生中断。这意味着您永远不会醒来,因为您依赖于睡眠期间发生的中断,而不是之前发生的中断。
飞思卡尔和爱特梅尔都使用相同的指令名称,但含义相反,真是太愚蠢了
这就是为什么我更喜欢的助记符,interrupts
因为noInterrupts
那里的意图非常明确。这些由核心包含文件中的定义实现。