/* Interrupt Vector Definitions*/ #define INT0 __vector_1 #define T0OVF __vector_17 #define SIGNAL __attribute__ ((signal)) /* AVR IO Registers Definitions */ #define PORTB (*(volatile unsigned char *)(0x25)) /* Data register, Port B */ #define DDRB (*(volatile unsigned char *)(0x24)) /* Data Direction Register, Port B */ #define DDRD (*(volatile unsigned char *)(0x2A)) /* Data Direction Register, Port D */ #define PIND (*(volatile unsigned char *)(0x29)) /* Input Pins, Port D */ #define SREG (*(volatile unsigned char *)(0x5F)) /* Status Register */ #define EICRA (*(volatile unsigned char *)(0x69)) /* Asynchronous External Interrupt Control Register A */ #define EIMSK (*(volatile unsigned char *)(0x3D)) /* External Interrupt Mask Register */ #define TCNT0 (*(volatile unsigned char *)(0x46)) /* Timer/Counter0 Register */ #define TIMSK0 (*(volatile unsigned char *)(0x6E)) /* Timer/Counter0 Interrupt Mask Register */ #define TCCR0A (*(volatile unsigned char *)(0x44)) /* Timer/Counter0 Control Register A */ void INT0 (void) SIGNAL; void T0OVF () SIGNAL; int main(void) { DDRB = 0xff; // Set PORTB to output PORTB = 0xff; // Turn off LEDs SREG |= 0x80; // Enable Interrupts EIMSK = 0x01; // Enable External Interrupt 0 EICRA = 0x02; // At faling edge TIMSK0 |= 0x01; // Enable Timer0 Overflow Interrupt while(1); return 0; } /* IRQ 0 Interrupt Handler */ void INT0 (void) { if(EICRA == 0x03) { // If IRQ0 is rising edge (button released) EICRA = 0x02; // Set IRQ0 to falling edge PORTB = 0xff; // Turn off LEDs TCCR0A &= ~0x07; // Disable TIMER0 } else { // IRQ1 is falling edge (button pressed) EICRA = 0x03; // Set IRQ0 to rising edge TCNT0 = 0x00; // Clear timer counter TCCR0A |= 0x05; // Start TIMER0 @ CLK/256 } } /* Timer1 Interrupt Handler */ void T0OVF () { PORTB = 0x00; }