Skip to main content
Engineering LibreTexts

29.2: External Interrupts

  • Page ID
    35916
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \) \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)\(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\) \(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\)\(\newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    Let’s consider an external interrupt first. In this case, the state change seen at an external pin causes an interrupt. We will use External Interrupt Request 0, also known as the INT0 vector. This interrupt examines state changes at PORTD.2, Uno pin 2. Our example will be fairly simple: we attach a passive switch using the internal pull-up to pin 2. When the switch is activated it will toggle an LED connected to Uno pin 8 (PORTB.0). The code follows:

    /* External Interrupt Example, INT0
       External interrupt pin lights an LED
    
       Active high LED attached to PORTB.0
       Switch on Uno pin 2, falling edge triggers external pin interrupt 0,
       ISR toggles LED at PORTB.0
    */
    
    #define LEDMASK 0x01
    
    void setup()
    {
        DDRB |= LEDMASK;
        // set Uno pin 2 for input with pullup
        DDRD &= ~(0x04);
        PORTD |= 0x04;
    
        EIMSK |= (1<<INT0);  // enable external interupt INT0 (Uno pin 2)
        EICRA |= (1<<ISC01); // trigger INT0 on falling edge
    }
    
    ISR(INT0_vect)
    {
        PORTB ^= LEDMASK;    // toggle LED
    }
    
    void loop()
    {
    }
    

    After setting the IO pins, the code sets the INT0 bit in the EIMSK register to enable the interrupt. The External Interrupt Control Register (EICRA) is programmed to trigger on a falling (negative going) edge. When the switch is activated, the falling edge triggers the ISR to run. The ISR simply toggles the bit that the LED is tied to. Note that there is no port setting and pin examination in the main code. In fact, loop() is empty and does nothing.

    Among other things, an external interrupt such as this is very useful for high importance items such as a panic switch.


    This page titled 29.2: External Interrupts is shared under a CC BY-NC-SA 4.0 license and was authored, remixed, and/or curated by James M. Fiore via source content that was edited to the style and standards of the LibreTexts platform; a detailed edit history is available upon request.