Topic 2 : External Interupts
Problem 1 : Write the C program using external interrupt ISR to scan INT0,INT and INT2 when INT-X is pressed, toggle The aprropriate
LED0,LED1and LED3 .
#include "avr/io.h"
#include "avr/interrupt.h"
int main (){
DDRD = 0xFF; // PA as an output
PORTD = 0xFF; //pull up resistor
MCUCR = 0x00; // make INT0 and INT1 low level triggered
//MCUCSR = (1<<ISC2); // make INT2 rising edge triggered, un-cmt to make INT2 rising edge, keep this to low level triggered
GICR = (1<<INT0)|(1<<INT1)|(1<<INT2);
sei (); // enable interrupts
while (1); // wait here
ISR (INT0_vect){ // ISR for external interrupt 0
PORTD ^= (1<<4) ; // toggle PORTD.4
ISR (INT1_vect){ // ISR for external interrupt 1
PORTD ^= (1<<5) ; // toggle PORTA.5
ISR (INT2_vect){ // ISR for external interrupt 2
PORTD ^= (1<<6) ; // toggle PORTA.6
}
Problem 2 : Convert the C Code in Problem 1 into Assembly Code
#include "[Link]"
.org 0x0000
rjmp main
.org 0x0002
rjmp EXT_INT0
.org 0x0004
rjmp EXT_INT1
.org 0x0006
rjmp EXT_INT2
main:
LDI R16,0xFF
OUT DDRD,R16
OUT PORTD, R16
LDI R16,0b00001011; MCUCR = 0b00001011;
OUT MCUCR,R16
;;LDI R16,0x00; un comment to make it rising edge again
; OUT MCUCSR,R16 ; MCUCSR = 0; // make INT2 rising edge triggered
LDI R16,(1<<INT0)|(1<<INT1)|(1<<INT2) ;
OUT GICR,R16 ; GICR = (1<<INT0)|(1<<INT1)|(1<<INT2) ;
sei ; sei(); // enable interrupts
While_1:
rjmp While_1
;---------------------------------------------------------------------------------------
EXT_INT0:
ldi R17,(1<<4)
IN R16,PORTD
EOR R17,R16
OUT PORTD, R17
RETI
;---------------------------------------------------------------------------------------
EXT_INT1:
ldi R17,(1<<5)
IN R16,PORTD
EOR R17,R16
OUT PORTD, R17
RETI
;---------------------------------------------------------------------------------------
EXT_INT2:
ldi R17,(1<<6)
IN R16,PORTD
EOR R17,R16
OUT PORTD, R17
RETI
Advance questions : Compile Assembly Code in Problem 2 into AVR Binary Machine Code