EXTERNAL INTERRUPTS ON THE ATmega8


INTRODUCTION:

In the previous section I talked about the basics of interrupts. In this section, we will talk about the first type of device interrupts called external interrupts. These interrupts are basically called on a given status change on the INTn pin. This is essentially an input interrupt and is great to use for applications when you might need to react quickly to an outside source, such as a bumper of your robot hitting the wall or to detect a blown fuse.


HARDWARE:

If you look at the AVR data sheet, the second page shows the pin configuration of the AVR chip. All the PA#, PB#, PC# and PD# could be configured as an outputs.

ATmega8 - INTx

Figure 1: ATmega8 - External Interrupt Pins

Hardware wise there is not difference between External Interrupts and Inputs so don't be afraid to reread the Digital Input Tutorial if you need a refresher.

If you look at the AVR pinout diagram you will see the INTx which are used for External Interrupts.


THEORY OF OPERATION:

External interrupts are fairly powerful, they can be configured to trigger on one of 4 states. Low level will trigger whenever the pin senses a LOW (GND) signal. Any Logic Change trigger at the moment the pin changes from HIGH (Vcc) to LOW (GND) or from LOW (GND) to HIGH(Vcc). On Falling Edge will trigger at the moment the pin goes from HIGH (Vcc) to LOW (GND). On Rising Edge will trigger at the moment the pin goes from LOW (GND) to HIGH (Vcc). The best part is that you can configure each INTx independently.

External interrupts use the below 3 registers. Which you could find under the "External Interrupts" section of the datasheet.

7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0 bit
MCUCR SE SM2 SM1 SM0 ISC11 ISC10 ISC01 ISC00

MCU Control Register

ISCx1 ISCx0 DESCRIPTION
0 0 Low level of INTx generates an interrupt request
0 1 Any logic change on INTx generates an interrupt request
1 0 The falling edge of INTx generates an interrupt request
1 1 The rising edge of INTx generates an interrupt request

ISC Bits Settings

7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0 bit
GICR INT1 INT0 - - - - IVSEL IVCE

General Interrupt Control Register

7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0 bit
GIFR INTF1 INTF0 - - - - - -

General Interrupt Flag Register

When the event specified by the Interrupt Sense Control (ISCxy) bits in the MCU Control Register (MCUCR) is sensed on the INTx pin, the External Interrupt Flag x (INTFx) in the General Interrupt Flag Register (GIFR) is set HIGH (1). If the I-bit in SREG and the INT1 bit in the GICR are both HIGH(1) the MCU will jump to the corresponding vector. The Flag is set to LOW (0) when the INTx_vect routine is executed.


SOFTWARE:

The external interrupt code is fairly simple, just declare your INTx pins as inputs, set the inputs as interrupts, turn on the interrupts, and finally don't forget your ISR routines.

ATmega8 Code:

    #include <avr/io.h>
    #include <avr/interrupt.h>

    int main(void)
    {
        DDRD &= ~(1 << DDD2 );     // Clear the PD2 pin
        // PD2 (INT0 pin) is now an input

        PORTD |= (1 << PORTD2);    // turn On the Pull-up
        // PD0 is now an input with pull-up enabled


        MCUCR |= (1 << ISC00);    // set INT0 to trigger on ANY logic change
        GICR |= (1 << INT0);      // Turns on INT0

        sei();                    // turn on interrupts

        while(1)
        {
            /* main program loop here */
        }
    }

    ISR (INT0_vect)
    {
        /* interrupt code here */
    }

I like big bots and I can not lie.


Cheers
Q