中断 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 的助记符,因为那里的意图非常明确。这些由核心包含文件中的定义实现。