Simulating Software Interrupts on ATmega328p


// might miss some includes
#include <util/delay.h>
#include <avr/interrupt.h>

#define DISABLE(REGISTER, BIT) (REGISTER) &= ~(1 << BIT)
#define ENABLE(REGISTER, BIT) (REGISTER) |= (1 << BIT)
#define TOGGLE(REGISTER, BIT) (REGISTER) ^= (1 << BIT)
#define TRIGGER(REGISTER, BIT) TOGGLE(REGISTER, BIT);TOGGLE(REGISTER, BIT)
#define IS_SET(REGISTER, BIT) (REGISTER & (1 << BIT)) > 0

ISR(INT0_vect)
{
    // toggle the LED
    TOGGLE(PORTB, PORTB5);
}

void InitGPIO()
{
    // make port output & HIGH
    // our power source
    ENABLE(DDRB, DDB4);
    ENABLE(PORTB, PORTB4);

    // make Port B5 output & LOW
    // Connected to an LED - Depending on the state of this, 
    // the LED is either on or off.
    ENABLE(DDRB, DDB5);
    DISABLE(PORTB, PORTB5);

    // Make Port D2 Input External Interrupt
    DISABLE(DDRD, DDD2);
    ENABLE(PORTD, PORTD2);
}

void InitINT0()
{
    // Manual - Page 80
    // The falling edge of INT0 generates an interrupt request.
    ENABLE(EICRA, ISC01);
    DISABLE(EICRA, ISC00);
}

void triggerINT0()
{
     ENABLE(DDRD, DDD2);
     ENABLE(PIND, PIND2);
     ENABLE(PORTD, PORTD2);
}

int main(void)
{
    InitGPIO();
    InitINT0();
    sei();
    while(1)
    {
        _delay_ms(1000);
        triggerINT0();
    }
}

That’s not the full code, but it’s used to depict my part that I’m trying to work on.
It seems weirdly that the interrupt is triggered exactly, when I enable(set to 1) all three of the register bits.

I’m not yet sure, why it needs explicitly to be all three of these registers that trigger my interrupt there.

And depending on the way the interrupt is triggered, it seems that the software interrupt needs to be triggered differently :smiley: that sounds like configuration fun for all cases for all interrupts.

2 Likes