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.
Atmega168 and peripheral interrupts
Started by ●December 4, 2005
Reply by ●December 7, 20052005-12-07
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(); } }
Reply by ●December 7, 20052005-12-07
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(); } }