1

I'm facing a problem programming an ATmega32A-PU regarding the use of Interrupt INT0. Everytime it's triggered (by rising edge on PD2) , it causes the MCU to (seemingly) reset, meaning it starts int main(void) from the beginning.

It's not the first time, I'm working with Interrupts and I don't see why it should behave like it does.

Appart from that, I'm also making use of 'ISR(TIMER0_COMP_vect)', which work's just fine.

#define F_CPU 16000000 // 16 MHz clock speed

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

volatile unsigned int T2StopFlag = 0;
volatile unsigned int initialized = 0;
volatile unsigned long millis_value = 0;


#include "Includes\csrc\u8g2.h"
#include "display.h"
#include "utility.h"

// (utility.h includes:)
/* ----------------------------------------------------------------------- */

IRS(INT0_vect)
{
        PORTA &= ~(1<<6);   // MotorOFF();      
        PORTA &= ~(1<<4);   // RV1OFF();        
        PORTA &= ~(1<<5);   // RV2OFF();        
        T2StopFlag = 1;     // T2StopFlag setzen
}


ISR(TIMER0_COMP_vect)           // ISR for millis();
{
    millis_value++; // Increment millisecond every 1ms
}

unsigned long millis()
{
    unsigned long m;
    
    cli();                  
    m = millis_value;
    sei();

    return m;
}


/* ----------------------------------------------------------------------- */


#include "systemcheck.h"
#include "executions.h"
#include "states.h"
#include "modusoperandi.h"


/* ----------------------------------------------------------------------- */

    
int main(void)
{   

// --- ISR for T2 (INT0) --- //   <- Causes program to restart.
    MCUCR = 0x03;   // 0b 0000 0011 -> INT0 rising edge, INT1 not
    GICR = 0x40;    // 0b 0100 0000 -> INT0 set, INT1 set INT2 not

    
// --- ISR for millis(); --- //  <- Works just fine.
    TCCR0 = 0x0B;   // Clock source: System Clock   // Mode: CTC top=OCR0
    TCNT0 = 0x00;   // Timer/Counter 0 initialization
    OCR0 = 0xF9;    // Clock value: 250.000 kHz (16MHz/64)
    TIMSK = 0x02;   // Enable compare match interrupt for timer 0
    
// --- Enable global interrupt --- //
    sei();


        // ---- StartUp Sequence ---- //
    
    StartUpSeqDemo();   // Run Start Up Sequence once
    ServiceModeReq();   // Request Command to enter Service Mode
    
    // ---- Loop ---- //


    while(1)
    {   
               /* ... */
        
    }   // while(1); end
}         // int main(void); end

What I tried:

  • Implementing INT0 as a ISR at rising edge on PD2.
  • suspected cli(); and sei(); in millis() {...} to cause the problem but I'm not getting a different result when commenting them out.
  • DMFR

What I ecpected to happen:

  • Program does it's thing, IRS triggers on rising egde, program continues what it was doing.

What actually resulted:

  • Program restarts, code before while(1) {} is being executed.

What I also noticed

I'm getting the following warnings on IRS(INT0_vect) {...}, but not on ISR(TIMER0_COMP_vect):

Warning     type of '__vector_1' defaults to 'int' [-Wimplicit-int]
Warning     return type defaults to 'int' [-Wimplicit-int]
Warning     control reaches end of non-void function [-Wreturn-type]

So I tried:

int IRS(INT0_vect)
{
            PORTA &= ~(1<<6);   // MotorOFF();      
            PORTA &= ~(1<<4);   // RV1OFF();        
            PORTA &= ~(1<<5);   // RV2OFF();        
            T2StopFlag = 1;     // T2StopFlag setzen
            
            return 0;
}

which reduces the warnings to:

Warning     type of '__vector_1' defaults to 'int' [-Wimplicit-int] 

Not quite sure I that's a related problem and wether thats a related problem.

Any thoughts are welcome.

Btw, please bear with me if I'm missing out on some information or something, I'll happily provide you with everything that helps.

Thanks for your time and effort!

M.Grae
  • 21
  • 5
  • 5
    Should IRS(INT0_vect) not be ISR(INT0_vect) ? – doron Jan 30 '23 at 16:12
  • How does this code even compile with `IRS(INT0_vect)`? – Marco Jan 30 '23 at 16:16
  • `int ISR(INT0_vect)` is always wrong, interrupts don't return _anything_. – Marco Jan 30 '23 at 16:17
  • OMG, I spent far too much time on that. Of cause, it's ISR, not IRS. Thank's for lending me your eyes. – M.Grae Jan 30 '23 at 16:22
  • That explains your reset, your MCU doesn't know which ISR to call and hence resets. How did the code compile in the first place though? – Marco Jan 30 '23 at 16:22
  • Not quite sure why compiling didn't give me an error but just a warning. Anyway, now the warning itself makes more sense, as well. Thanks for the help! – M.Grae Jan 30 '23 at 16:23
  • 2
    @Marco `int IRS(INT0_vect)` is a definiton of function named `IRS` with argument `INT0_vect` which type defaults to `int`. – dimich Jan 30 '23 at 16:31
  • 2
    When you use `ISR`, it's a macro/builtin that does special (non-standard) stuff to define/install an interrupt service routine. But, `IRS` is nothing special. So, `IRS(INT0_vect) { ... }` is treated by the compiler as an old K&R function definition. It is missing a return type (so it defaults to `int`). There are warnings enabled for that. `INT0_Vect` is treated as the name of the first _parameter_ of the `IRS` function. So, it is synthesizing the equiv of (ANSI): `int IRS(int INT0_Vect) { ... }` – Craig Estey Jan 30 '23 at 16:32
  • Thanks to all of you guys! I'd like to give you credits, but didn't earn enough reputation to do so .Anyway, my problem is solved! – M.Grae Jan 30 '23 at 17:34

0 Answers0