Hallo Forum, Ich habe ein problem mit dem ATmega8 im power down modus. nachdem der controller in den power down geschickt wurde, kann man den controller nicht mit dem pegelgetriggerten INT1 aufwecken. Sonderbar ist, daß der Controller aber mit der nächsten steigenden Flanke am INT1 wieder aufwacht. Ich habe ein kleines Program angeängt, das im prinzip mit einer LED winkt und danach in den sleep mode geht. Eine weitere LED zeigt an, sobald der IRQ ausgelöst wird. Habe ich irgend etwas übsersehen oder hat hat der Controller bei levelgetrigerten IRQ ein Problem? void go_idle(void); void go_power_down(void); /* ------------------------------------------------------------------------ - */ int main(void) { unsigned char timer0old=0,toggle; { hardwareInit(); odDebugInit(); DBG1(0x00, 0, 0); sei(); SET_LED2; timer0=0;//reset the timer which resets the LED's } for(;;) if (timer0 != timer0old) { timer0old=timer0; testloop++; if (testloop>4) { go_power_down(); testloop=0; // this command will be executed after power down and restart the cycle } } return 0; } /* ------------------------------------------------------------------------ - */ #define cbi(sfr, bit) ( sfr &= ~ _BV(bit)) #define sbi(sfr, bit) ( sfr |= _BV(bit)) void go_power_down(void) { //sbi (GIFR,INTF1); sbi (GICR,INT1); cbi (MCUCR,ISC11); cbi (MCUCR,ISC10); //Interrupt on low level triggered cbi (MCUCR,SM0); sbi (MCUCR,SM1); cbi (MCUCR,SM2); // configure the sleep mode to power down SM0,SM1,SM2=0,1,0 sbi (MCUCR,SE); //and start the sleep mode CLR_LED1; CLR_LED2; asm ("sleep"); cbi (MCUCR,SE); } INTERRUPT (SIG_INTERRUPT1) { char reg; timer0=0; //cli(); SET_LED1; SET_LED2; } INTERRUPT (SIG_OVERFLOW0) { static char t; if (t>=25) {timer0++; t=0; SET_LED2;} // delay to view the LED toggling else {t++; CLR_LED2;} }
...Und Du kriegst keine Warnmeldungen beim Compilieren? Welchen Compiler bzw. welche Version benutzt Du denn? Sieht ein bisschen nach AVR-GCC aus, aber nach einer steinalten Version. Ein Interrupt-Handler wird in AVR-GCC mit aktueller AVR-libC mit "ISR" eingeleitet und nicht mit "INTERRUPT". Afair wurde bei früheren Versionen ein unterbrechbarer Interrupt-Handler mit "interrupt" (klein geschrieben) eingeleitet... Unterbrechbare ISRs sind aber in Deinem Fall (und ganz besonders bei Level-Interrupts) alles andere als empfehlenswert bzw. im letzten Fall sogar "tödlich"...
Der Compiler ist ein ca. 2 jahre alter AVR-GCC. Meinst Du mit "tödlich" einen möglichen Stack-overflow ? Ich habe mal versucht, innerhalb der ISR den IRQ zu sperren, allerdings mit keinem Erfolg. Sobald der IRQ getriggert wird, sollte eine LED leuchten was aber nicht passiert. Kann es sein daß beim ersten push sofort wieder ein IRQ ausgelöst wird? Dann würde sich der arme Prozessor immer wieder in der selben Schleife befinden. Sollte das passieren, gibt es ein Mittel dagegen?
Wenn Du keinen neuen AVR-GCC hast und auch nicht updaten willst, dann benutze wenigstens "SIGNAL" anstelle von "INTERRUPT". Ein Level-Interrupt wird immer so lange aufgerufen, wie der Pegel anliegt. Wenn die ISR auch noch unterbrechbar ist, kommst Du da erstens nie wieder raus und zweitens tritt dann mit einiger Wahrscheinlichkeit ein Stack-Overflow auf.
Ein pegelgetriggerter Interrupt wird solange aufgerufen, wie der Pegel anliegt. Folglich wird der Controller für eben diese Zeit mit nichts anderem als mit Interrupts beschäftigt sein. Der Power-Up Interrupt sollte also den externen Interrupt abschalten. Aber nicht per SEI, sondern im GICR.
Erstmal Danke für Eure Inputs. Ich habe nun mal die verschiedenen "Wörter" für INTERRUPT, SIGNAL und ISR ausprobiert und siehe da,- der Compiler reagiert tatsächlich unterschiedlich. Mit SIGNAL klappt's bei meiner Version nun. Danke nochmals :-)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.