External Interrupt

Back to start page

 

Try interrupt. This is an example of a program for ATmega that switches a light emitting diode, LED, On/Off for each keystroke, and is utilizing interrupt.

The key is connected between pin 4, INT0/PD2, and ground. When you press the button, input is '0'; when you release the button, the input signal instead is taken from a so-called "Pull Up" resistor and then becomes '1'. Without the PullUp resistor the input had been left completely "open" when releasing the button, and then been susceptible to interference from the environment - and the operation had become very uncertain.
PullUp-resistor nvolves a certain cost, so therefore there is a possibility to program the chip to use an "embedded" pullup resistor. If a pin is programmed as an input, and '1' is output to the pin, then the internal PullUp resistor will be activated.

DDRD  &= ~( 1 << PD2 );      // pin 4 PD2 direction is input, Butt (INT0)
PORTD |=  ( 1 << PD2 );      // Enable pullup resistor for INT0

ATmega has vectorized interrupt. There are 24 different interrupt sources, and each source is routed to a separate interrupt.

At interrupt the corresponding interrupt routine will be run. While an interrupt routine is run further interrupts are disabled.

To use the external interrupt INT0 you write an interrupt routine:

#include <avr/interrupt.h>

ISR( INT0_vect )
{
   /* write your interrupt subroutine here */ 
}

Interrupt is enabled at the local and global level.

For INT0 interrupt you can choose between low level, or at any change, or between positive or negative edge.

EIMSK |=  ( 1 << INT0 );    // Local Enable external interrupt INT0
EICRA &= ~( 1 << ISC00 );   // INT0 on falling edge
EICRA |=  ( 1 << ISC01 );   // INT0 on falling edge
sei();                      // Global Enable interrupts

Contact bounces

A Pushbutton "bounces" when it closes the pin to the ground. It therefore makes many attempts to interrupt each time you press the button. In the interrupt routine a delay routine is used to wait out the contact bounces before returning to the main program and interrupt again becomes allowed.

ISR( INT0_vect )
{

    PORTB ^= ( 1 << PB5 );    // Toggle LED on pin 13 (PB5)
     _delay_ms(200);          // wait for contact bounces to settle
    EIFR  |= ( 1 << INTF0 );  // Clear INTF0 flag probably set by bounces during wait
}

Interrupt flag is automatically reset during the interrupt routine, but this is, unfortunately, done before leaving the routine. Contact bounces may activate the interrupt flag again so therefore you have to reset it as the last thing you do in the routine.

The full program is available here:


Back to start page

 


William Sandqvist    william@kth.se