0

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]

Binnudeya
  • 1
  • 2
  • @RTT I tried that, didn't work either, from my understanding and the link you provided it's the same as set the I-bit in the SREG, is it not? – Binnudeya Dec 07 '19 at 03:27
  • Yes it turns out you are correct, my mistake I thought those registers were for something else. I've updated my answer with another solution I've tested on an ATMega168. Let me know if that one works for you! – RTT Dec 07 '19 at 03:54
  • @RTT..No, still doesn't work. The EIMSK and the EICRA are the registers' names in the ATMEGA168 I think. And they're the equavilant according to your comments to the GICR & MCUSR registers. I'm using a proteus simulator not an actual kit, so I can't really know if there's any dimming or not, but I don't understand the motive for the PORTC to be from 0 to 255 if the external ISR is to be triggered with an external switch (falling edge setting) unrelating to the actual ISR routine? – Binnudeya Dec 07 '19 at 23:43
  • In both blocks of my code, setting PORTC to 0 or 255 is equivalent to writing 0x00 or 0xFF or 0b00000000 or 0b11111111. It's just a different form of notation. Do you happen to have any schematics from the simulator you can post? – RTT Dec 08 '19 at 15:54
  • I understand the diffrent formats, but why the edging in the first place. Also edited the post with a screenshot from the Proteus Simulator. @RTT – Binnudeya Dec 10 '19 at 01:39

1 Answers1

2

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);
    }
}
RTT
  • 56
  • 5