EmbeddedRelated.com
Forums
Memfault Beyond the Launch

Atmega168 and peripheral interrupts

Started by P.Marek December 4, 2005
I have a problem with an atmega168.

On my test board I have a jumper on PB1 and a LED on PD5, using
internal 8MHz RC-clock.

Given the following program:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/signal.h>


    INTERRUPT(SIG_PCINT0)
    {
        unsigned short i;
        char j;

        for(j=0; j<3; j++)
        {
            PORTD ^= _BV(PD5);

            for(i=0; i<35000; i++);
        }
    }

    int main(void)
    {
        // INITIALIZE 8MHz/256 -> 31 250 Hz
        CLKPR=_BV(CLKPCE);
        CLKPR=_BV(CLKPS3);

        // enable PD5 as output
        DDRD|= _BV(PD5);

        // enable pullup
        DDRB=0;
        PORTB=_BV(PORTB1);

        // allow PCINT1
        PCMSK0=_BV(PCINT1);
        PCICR=_BV(PCIE0);

        // enable int
        sei();

        /* blink, blink ... */
        SIG_PCINT0();
        while (1) {
            sleep_mode();
        }
    }
This works. But if I remove the call to SIG_PCINT0() before the loop in
main() I don't get any interrupts.

Why is that so? And how can this be solved?
Is there an initial interrupt generated from using the pull-up, which
doesn't get routed to the interrupt routine as soon as sei() is called?


It's not the "return from interrupt" in SIG_PCINT0(). I tried by
defining a SIG_WDT() and calling that from main() instead, but that
didn't work, either.


Help, please?

Thank you very much.

I found the problem.
I had a wrong signal name - which meant that each interrupt lead to a
reset.


Here's the working program.
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/sleep.h>
    #include <avr/signal.h>


    // PD5=OC0B=T1
    SIGNAL(SIG_PIN_CHANGE0)
    {
        PORTD ^= _BV(PD5);
    }


    int main(void)
    {
        // ENable int
        sei();

        /* INITIALIZE 8MHz/256 -> 31 250 Hz */
        CLKPR=_BV(CLKPCE);
        CLKPR=_BV(CLKPS3);

        /* enable PD5 as output */
        DDRD|= _BV(PD5);

        //PCINT1 erlauben
        PCMSK0=_BV(PCINT1);
        PCICR=_BV(PCIE0);

        //Pull-Up
        DDRB=0;
        PORTB=_BV(PORTB1);

        /* BLINK, BLINK ... */
        while (1) {
                sleep_mode();
        }
    }

I found the problem.
I had a wrong signal name - which meant that each interrupt lead to a
reset.


Here's the working program.
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/sleep.h>
    #include <avr/signal.h>


    // PD5=OC0B=T1
    SIGNAL(SIG_PIN_CHANGE0)
    {
        PORTD ^= _BV(PD5);
    }


    int main(void)
    {
        // ENable int
        sei();

        /* INITIALIZE 8MHz/256 -> 31 250 Hz */
        CLKPR=_BV(CLKPCE);
        CLKPR=_BV(CLKPS3);

        /* enable PD5 as output */
        DDRD|= _BV(PD5);

        //PCINT1 erlauben
        PCMSK0=_BV(PCINT1);
        PCICR=_BV(PCIE0);

        //Pull-Up
        DDRB=0;
        PORTB=_BV(PORTB1);

        /* BLINK, BLINK ... */
        while (1) {
                sleep_mode();
        }
    }


Memfault Beyond the Launch