Будет ли прерывание 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
Без этого перед сном может произойти прерывание. Это означает, что вы никогда не просыпаетесь, потому что полагались на прерывание, происходящее во время сна, а не перед ним.
Как чудесно идиотски и Freescale, и Atmel используют одинаковые названия команд, но с перевернутыми значениями
Именно поэтому я предпочитаю мнемонику interrupts
и noInterrupts
, потому что цель там очень ясна. Они реализованы с помощью определений в основных включаемых файлах.