Interrupt Service Routine. A function which gets called in response to an interrupt signal.

Interrupts are widely used on processors to manage asynchronous events - that is, events that happen in an unpredictable way, such as someone closing a switch, receiving incoming serial data, a timer overflowing and so on.

The Atmega328P processor, used in the Arduino Uno, Duemilanove, Pro Mini, Nano, and others, has 25 possible interrupt events, in addition to Reset.

They are:

 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)

The name of the interrupt handler vector is in parentheses.

If an interrupt event occurs (for example, Timer 0 overflows), and that particular interrupt is enabled, and interrupts are currently globally enabled, then the processor will jump to the appropriate interrupt vector in that list, at the completion of the current instruction.

Interrupts are not serviced in the middle of an instruction. If multiple interrupt events have occurred, the higher priority one (higher up the above list) will be serviced first.

Once the processor jumps to service an interrupt, further interrupts are globally disabled. They are enabled again automatically when the Interrupt Service Routine (ISR) returns. (These remarks apply to the AVR range of processors, SAM/ARM and Intel ones may behave slightly differently)

Some interrupts are already handled by libraries (eg. The millis library for TIMER0_OVF_vect and the HardwareSerial library for USART_RX_vect, USART_UDRE_vect and USART_TX_vect). However if you write your own they typically look like this:

ISR(WDT_vect)
  {
  // interrupt handling code here
  }

General tips for writing ISRs

  • Keep the ISR code short
  • Don't use delay()
  • Don't do serial prints
  • Make variables shared with the main code volatile
  • Variables shared with main code may need to be protected by "critical sections"
  • Don't try to turn interrupts off or on inside an ISR
history | excerpt history