mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik sleep, brauche konzept


Autor: Can Cobe (moklok)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,

es geht um den sleep modus auf einem meiner mikrokontroller (sleep=keine 
CPU Taktung).  meine interrupts muessen sehr kurz sein.  deshalb setze 
ich in meinen interruptroutinen nur ein flag, dass etwas gemacht werden 
muss.  die eigentliche arbeit wird dann in der main gemacht, die ja 
durch die interrupts geweckt wird

void main(){

  while(1){

    if(TueEtwasFlag1){
       TueEtwasFlag1=0;
       TueEtwas1();
    }
    if(TueEtwasFlag2){
       TueEtwasFlag2=0;
       TueEtwas2();
    }

    if(kein Flag gesetzt){
      // <------------------- problemzeitpunkt
      sleep();
    }

  }
}

mein problem ist nun, dass diese Flags irgendwann gesetzt werden können. 
mal kommen diese sehr oft und mal sehr selten.  wenn nun ein flag 
gesetzt wird, während des "problemzeitpunkts" geht mein kontroller 
schlafen, obwohl noch was zu tun ist.

wie kann ich dafuer sorgen, dass der kontroller nur schlafen geht, wenn 
auch wirklich keine arbeit mehr anliegt????

danke schonmal fuers lesen

moklok

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Can Cobe (moklok)

>wie kann ich dafuer sorgen, dass der kontroller nur schlafen geht, wenn
>auch wirklich keine arbeit mehr anliegt????

Das muss deine State Machine in der Hauptschleife machen. Siehe [[Sleep 
Mode]] und Statemachine

MFG
Falk

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>wie kann ich dafuer sorgen, dass der kontroller nur schlafen geht, wenn
>auch wirklich keine arbeit mehr anliegt????
Wichtig ist, erst mal zu erkennen, dass keine Arbeit mehr anliegt.
Kannst du das? Welche Art von Arbeit (Interrupts) ist das?

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Can Cobe schrieb:
> wie kann ich dafuer sorgen, dass der kontroller nur schlafen geht, wenn
> auch wirklich keine arbeit mehr anliegt????

Einfach Interrupt sperren:
    cli();
    if(kein Flag gesetzt){
      // <------------------- kein problemzeitpunkt
      sei();
      sleep();
    }
    sei();


Peter

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
   cli();
    if(kein Flag gesetzt){
      // <------------------- kein problemzeitpunkt
      sei();
       // <------------------- jetzt ist hier problemzeitpunkt
      sleep();
    }
    sei();

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter schrieb:
>
>    cli();
>     if(kein Flag gesetzt){
>       // <------------------- kein problemzeitpunkt
>       sei();
>        // <------------------- jetzt ist hier problemzeitpunkt
>       sleep();
>     }
>     sei();
> 

Nein, denn nach SEI wird garantiert noch der folgende Befehl ausgeführt, 
also das SLEEP, ehe in einen Interrupt gesprungen werden kann.


Peter

Autor: Michael Buesch (mb_)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
AVR libc doku:
    As the \c sleep_mode() macro might cause race conditions in some
    situations, the individual steps of manipulating the sleep enable
    (SE) bit, and actually issuing the \c SLEEP instruction, are provided
    in the macros \c sleep_enable(), \c sleep_disable(), and
    \c sleep_cpu().  This also allows for test-and-sleep scenarios that
    take care of not missing the interrupt that will awake the device
    from sleep.

    Example:
    \code
    #include <avr/interrupt.h>
    #include <avr/sleep.h>

    ...
      set_sleep_mode(<mode>);
      cli();
      if (some_condition)
      {
        sleep_enable();
        sei();
        sleep_cpu();
        sleep_disable();
      }
      sei();
    \endcode

    This sequence ensures an atomic test of \c some_condition with
    interrupts being disabled.  If the condition is met, sleep mode
    will be prepared, and the \c SLEEP instruction will be scheduled
    immediately after an \c SEI instruction.  As the intruction right
    after the \c SEI is guaranteed to be executed before an interrupt
    could trigger, it is sure the device will really be put to sleep.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
AVR Instruction Set:

"SEI – Set Global Interrupt Flag
Description:
Sets the Global Interrupt Flag (I) in SREG (Status Register). The 
instruction following SEI will be executed before any pending 
interrupts."


Peter

Autor: Can Cobe (moklok)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
haha,  danke!!!

das mit dem "executed before any pending interrupt" wusste ich noch 
nicht und erleichtert die aufgabe immens...

Autor: X- Rocka (x-rocka)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und ich ärgere mich gerade über die AVR Datenblätter (ATmega128RFA1, 
ATmega1281)... Da steht alles mögliche über die sleep modes, aber 
nirgends, dass man nach dem setzen der ganzen Register noch den 
Assembler Befehl "sleep" braucht!

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
X- Rocka schrieb:
> Da steht alles mögliche über die sleep modes, aber
> nirgends, dass man nach dem setzen der ganzen Register noch den
> Assembler Befehl "sleep" braucht

naja, aber durch mitdenken fragt man sich ja ab wann der Prozessor nun 
wirklich schläft oder nicht?

Autor: X- Rocka (x-rocka)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter schrieb:
> X- Rocka schrieb:
>> Da steht alles mögliche über die sleep modes, aber
>> nirgends, dass man nach dem setzen der ganzen Register noch den
>> Assembler Befehl "sleep" braucht
>
> naja, aber durch mitdenken fragt man sich ja ab wann der Prozessor nun
> wirklich schläft oder nicht?

Hast ja recht, bin ja auch irgendwann drauf gekommen, dass nur Register 
setzen es nicht sein kann. Aber auch erst, als ich mir das Datenblatt 
samt Instruction Set des ATmega1281 angesehen habe. Spiele nämlich 
gerade wieder mit dem RFA1 rum, und da haben die nicht das Instruction 
Set reingepackt.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
X- Rocka schrieb:
> Da steht alles mögliche über die sleep modes, aber
> nirgends, dass man nach dem setzen der ganzen Register noch den
> Assembler Befehl "sleep" braucht!

ATmega1281 Datenblatt S.56:

"• Bit 1 – SE: Sleep Enable
The SE bit must be written to logic one to make the MCU enter the sleep 
mode when the SLEEP instruction is executed."

Also ich finde das eindeutig.

Wenn ich eine Funktionseinheit im AVR programmiere, gehe ich immer in 
die dafür zuständige "Register Description" und klappere die ab.
Dann läuft auch fast alles auf Anhieb.


Peter

Autor: X- Rocka (x-rocka)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger schrieb:

> Also ich finde das eindeutig.

Ja, ist es. Zu viel zu schnell gewollt und nicht gründlich genug 
gelesen.

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.