www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATMega 8 power down pegelgetriggert wake


Autor: garfield (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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;}

}


Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...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"...

Autor: garfield (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: garfield (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 :-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.