An Example

external INT

OK, enough with politics, time to see how we implement interrupts in practice. Note, that each compiler implements interrupts in a different way since the C language by itself, does not determine the way interrupts should be implemented. Thus, we will stick to gcc. Do you remember our example with the button and the LED? Have a look at the following piece of code that shows the use of the external interrupt 0 and we will discuss it. We are using ATMega8 and the button is connected to pin4, PD2(INT0).


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

// Enable INT0 External Interrupt
GICR |= 1<<INT0;

// Falling-Edge Triggered INT0
MCUCR |= 1<<ISC01;

// Enable Interrupts
sei()
 
int main(void)
{
   while (forever)
   {
   }
}

// External Interrupt 0 ISR
SIGNAL(SIG_INTERRUPT0) 
{
   PORTB &= ~(1<<4);
}
 

The first thing your eye will catch is the ISR. The SIGNAL keyword tells the compiler that this is an ISR. The SIG_INTERRUPT0 keyword just indicates that this ISR is for the external interrupt 0. Note, that the ISR header is not declared anywhere else in the program.

Before you get interrupts you have to enable them. It comes down to enabling a specific interrupt; setting INT0 bit in the GICR register in our case and enabling the global interrupt flag with the sei() macro. Alternatively, you could use the asm("sei") command for the same thing. Now, according to our setup we want a falling-edge triggered interrupt, this is why ISC01 is set.

Now you see that our main loop is empty, meaning that our micro will keep doing nothing, it will just enter the ISR when the button is pressed. Of course, you could have any piece of code in the main loop.

There is one thing you should take care of with interrupts, an ISR has to be quick. Be quick or be dead as some friends of mine suggest. There are many tasks for a microcontroller that rely on timing, for example the 1-wire protocol does that. If you have a long ISR and an interrupt hits when a timing-sensitive routine is executed, your code will brake. If you can 't help it, just protect any sensitive code. Disabe interrupts with cli() before the critical code and enable them afterwards.

 
 
victor@avrtutor.com