Using External Interrupt in AVR

July 25, 2009 by admin
Filed under: Uncategorized 

External Interrupts in AVR ATmega16/32/8

ATmega16/32 has Three pins which can be used to trigger external hardware interrupt to the controller. While ATmega8 has two external interrupt in it.

As ATmega16 & ATmega32 are pinwise compatible it has facility for external hardware interrupt at these pins.

INT0 – External Interrupt 0 – PIN 16/PORTD2

INT1 – External Interrupt  1 – PIN 17/PORTD3

INT2 – External Interrupt 2 – PIN 3/PORTB2

Suppose we have a task to blink a led whwnever a high to low edge is detected on the corresponding External Interrupt Pin. So when i write the code for that purpose it is said that i am writing an external interrupt service routine or interrupt handeller.

Here is the circuit diagrm for the task…

int0

Below is a description of all the registers related to the interrupts…

1. We must set I (Interrupt) Flag high in Status register taht is SREG to use any kind of interrupts. This flag can be set by software using instruction like SEI or CLI in asm but in ‘C’ we can directly call functions like “sei()” to set I flag and “cli()” to reset I flag.

2. 6th bit of GICR taht is General Interrupt Control Register must keep high to use external interrupt 0 in your application. INT0 bit can be set to one by executing following statment.

GICR=(1<<INT0); // similarly for INT1 or INT2

3. Another very important register is MCUCR (MCU control register). here is a short description of how it affects external interrupt operation.

atmel_mcucr

ISC01                   ISC00                           Description

0                              0                                 Low level of INT0 generates an interrupt

0                              1                                  Any logical change on INT0 generate

1                              0                                 Falling edge of INT0 generates interrupt

1                              1                                  Rising edge of INT0 generates interrupt]

Similar kind of bits are there for INT1 and INT2 in corresponding registers.

Here is the code in WinAVR to handle a external interrupt request.

#include<avr/io.h>
#include<avr/interrupt.h>  // header that defines addresses for INT vect
#include<util/delay.h>
#include<compat/deprecated.h>
int main(void)
{
DDRD=0x00;
DDRA=0xFF;
PORTD=0xFF;   // PIN INT0 initially pulled high
PORTA=0x00;   // LED initially Off
sei();                 // Interrupt flag set
GICR=1<<INT0;   // INT0 enabled
sbi(MCUCR,1);       // falling edge at INT0 generates interrupt
cbi(MCUCR,0);
while(1==1);
return 0 ;
}

SIGNAL(    SIG_INTERRUPT0 ) // SIGNAL is a macro for interrupts
{
PORTA=0xA0;
_delay_ms(200);
PORTA=0x50;
_delay_ms(200);
PORTA=0x00;
}

Similar kind of code can be written for INT1 or INT2. Whatever you want to do on interrupt call just write it inside SIGNAL(int vector){} and that’s it.

Contact-

devesh samaiya

devesh@electroons.compre

Comments

3 Comments on Using External Interrupt in AVR

  1. simin on Tue, 11th May 2010 6:09 am
  2. what’s the meaning of ” _delay_ms(200)” and _delay_us(100)” ?

  3. admin on Wed, 12th May 2010 2:26 am
  4. _delay_ms(200) // 200 miliseconds delay
    _delay_ms(100) // 100 microseconds delay

  5. AvrLabCom on Wed, 30th Jun 2010 4:05 am
  6. very usefull, is here an simple article about tomer-counters? Because it is no way without interrupts and timer-counters/

Tell me what you're thinking...
and oh, if you want a pic to show with your comment, go get a gravatar!





Anti-Spam Protection by WP-SpamFree