AVR microcontroller interrupts using WINAVR

I can’t imagine a microcontroller without interruptions. Without interrupts, you would have to make loops to check if one or another event occurred. Polling has many disadvantages like programs have to make loops, which takes valuable microcontroller resources. These resources may be used for other data processing tasks. This is why the microcontroller comes with built-in interrupt support. Instead of checking events, the microcontroller can interrupt normal program flow and jump to interrupt the service subroutine.

During an interrupt, the microcontroller stops the task at the current point, saves necessary information to stack, and gives resources to interrupt the subroutine. When interrupt subroutine finishes, and then normal program flow continues.

In assembler your program would start with interrupt table:

avr interrupt table

After the table goes the main program (RESET) and other interrupt subroutines where the program jumps after the interrupt occurs.

C Compiler creates this table while compiling, but how about interrupt handling routines.

First of all to make the compiler understand interrupt macro command include desired library;

#include "avr\interrupt.h"

All interrupts then can be described using the macro command: ISR(), for instance:

ISR(ADC_vect)
{
//Your code here
}

This routine is for ADC complete conversion handler. This macro command is convenient for handling all unexpected interrupts. Just create a routine like this;

ISR(_vector_dfault)
{
//your code here;
}

If you want to describe an empty interrupt (puts reti in interrupt table) just use:

EMPTY_INTERRUPT(ADC_vect)

Example:

Simple program:

#include "avr\io.h"
#include "avr\iom8.h"
#include "avr\interrupt.h"
#define outp(a, b) b = a
#define inp(a) a
uint8_t led;
ISR(INT0_vect) { /* signal handler for external interrupt int0 */
led = 0x01;
}
ISR(INT1_vect) { /* signal handler for external interrupt int1 */
led = 0x00;
}
int main(void) {
outp(0x01, DDRB); /* use PortB for output (LED) */
outp(0x00, DDRD); /* use PortD for input (switches) */
outp((1<<
sei(); /* enable interrupts */
led = 0x01;
for (;;) {
outp(led, PORTB);
} /* loop forever */
}

Leave a Reply