Binnudeya
Binnudeya

Reputation: 1

ISR_INT0_PD2 won't work but main function is infinitely working ATMEGA32

The below is a code to enable interrupt INT0_vect when PD2 is pressed. The code doesn't ever execute the ISR, but always executes the counter loop from 0 to 9 on the 7 segment in PORT C in the main Function. Also tried the sei(); instead of enabling the I-bit in the SREG. Any ideas?


        #include <avr/io.h>
        #include <avr/interrupt.h>
        #include <util/delay.h>

        #define    ISR_INT0_PD2    INT0_vect  

        ISR( ISR_INT0_PD2 ){
            PORTC = 0x00;
           _delay_ms(100);
        }
        int main(void)
        {
            int i=0;
            DDRC=0xff;          //portc is o/p
            PORTC=0x00;         // all pins on portc is 0 volt
            MCUCR |= (1<<1);   // falling edge
            GICR |=(1<<6);     // enable INT0 set pin6
            SREG |=(1<<7);     // set GIE pin7
            while(1)
            {
                for(i=0;i<10;i++)
                {
                    PORTC=i;
                    _delay_ms(1000);
                }
            }
        }

[Below is the screenshot from the simulator I've been using]

Upvotes: 0

Views: 304

Answers (1)

RTT
RTT

Reputation: 56

For the interrupt to execute you need to call sei() defined in <avr/interrupt.h>.

https://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html#gaad5ebd34cb344c26ac87594f79b06b73

EDIT: I was mistaken when I removed the line SREG |= (1 << 7) according to my link that is equivalent to sei(); After I wrote the below example I realized the registers are named differently on the ATMega32, so unfortunately the code below won't run.

Based on the data sheet for an ATMega32 your code should work, have you tried removing the for loop and driving PORTC to logic high (e.g. PORTC = 255)? I noticed when I was writing the code for the ATMega168 that the LED I was using was very dim with the code in your while loop. Also check that INT0 pin is connected via pull-up/pull-down resistor.

This is the code that works on my ATMega168, if I swap the register names to the ones used on the ATMega32 I end up with your code:

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

#define    ISR_INT0_PD2    INT0_vect  

ISR( ISR_INT0_PD2 ){
    // If there is a logic change on any pin hold the pins attached to PORTC low for 100ms.
    PORTC = 0;
    _delay_ms(100);
    // Relase PORTC to logic high.
    PORTC = 255;
}

int main(void)
{
    DDRC = 255;            // Set all pins on PORTC to be outputs.
    PORTC= 255;            // Set all pins on PORTC to be logic high.

    EIMSK = 0b00000001;    // Set external interupt request enable.

    EICRA = 0b00000001;    // Set the external interrupt control register A to so that 
                           // any logical change on INT0 generates an interrupt request.

    sei();                 // Set global interupts enable.

    while(1)
    {
        PORTC=255;         // Blink the entire PORTC bank.
        _delay_ms(20);
        PORTC=0;
        _delay_ms(20);
    }
}

Upvotes: 2

Related Questions