We have looked at the basics of AVR Interrupts, now let us go ahead and use the External Interrupts feature on the AVR MCUs.
Steps to configure the Interrupts:
- Set Global Interrupt(I-bit) Enable bit in the AVR Status Register(SREG)
- Set INT1 and INT0 bits in the General Interrupt Control Register (GICR)
- Configure MCU Control Register (MCUCR) to select interrupt type.
- Handle the interrupt in the Interrupt Service Routine code.
Contents
The Registers
General Interrupt Control Register (GICR)
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|
INT1 | INT0 | INT2 | - | - | - | IVSEL | IVCE |
MCU Control Register (MCUCR)
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|
SE | SM2 | SM1 | SM0 | ISC11 | ISC10 | ISC01 | ISC00 |
ISC01 | ISC00 | Description |
---|---|---|
0 | 0 | The low level of INT0 generates an interrupt request. |
0 | 1 | Any logical change on INT0 generates an interrupt request. |
1 | 0 | The falling edge of INT0 generates an interrupt request. |
1 | 1 | The rising edge of INT0 generates an interrupt request. |
General Interrupt Flag Register(GIFR)
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|
INTF1 | INTF0 | INTF2 | - | - | - | - | - |
We will connect two switches to the two interrupt pins and show the status on a LCD. The connections are shown in the image below.
Hook Up
The Code
#include<avr/io.h> #include<avr/interrupt.h> #include<util/delay.h> #include "lcd.h" volatile int cnt_zero,cnt_one; ISR (INT0_vect) //External interrupt_zero ISR { cnt_zero++; } ISR (INT1_vect) //External interrupt_one ISR { cnt_one++; } int main() { DDRC=0xff; //Configure PORTC(Lcd databus) as output DDRD=0xe0; //Configure INT0,INT1 as input and PORTD5-PORTD7(rs,rw,en) as output LCD_SetUp(PB_0,PB_1,PB_2,P_NC,P_NC,P_NC,P_NC,PB_4,PB_5,PB_6,PB_7); LCD_Init(2,16); GICR=0xc0; //Enable External Interrupts INT0 and INT1 MCUCR=0x08; //Configure INT0 active low level triggered and INT1 as falling edge sei(); // Enable global interrupts by setting global interrupt enable bit in SREG while(1) { LCD_Printf("EINT0:%4u\n",cnt_zero); LCD_Printf("EINT1:%4u\n",cnt_one); } }