Sleepmode per INT0 Frage

Gast #1316937
Lesenswert?

Hallo liebes Forum :-),

ich bin Anfänger und suche gerade eher nach einer Idee, folgendes habe 
ich vor:

Ich würde gern meinen Merga32 über den INT0 in den Tiefschlaf schicken.
Das ganze soll so ablaufen das der Mega sein Hauptprogramm abarbeitet 
solang ich auf INT0 high habe und sobald low anligt soll er schlafen 
gehn bis wieder high ansteht.

Wie könnte ich das denn angehen?

Liebe Grüße
Marcel
#1317087
Lesenswert?

Da würd ich gar keinen Interrupt nehmen sondern alles in der 
Hauptschleife erledigen. Dadurch schickst du den µC auch erst dann 
schlafen wenn es wirklich nichts mehr zu tun gibt.

> damit das der Pegel
> ja permanent ist und nicht nur ein Impuls.

Die Impulsauswertunt ist dann auch kein Problem mehr.
In den Tiefschlaf gehts erst dann, wenn auf 2 aufeinanderfolgenden 
Durchläufen durch die Hauptschleife ein 1-0 Übergang erkannt wird
1
   ...
2

3
   prevLevel = 1;
4
   while( 1 )  {
5
     ....
6

7
     thisLevel = ... Status vom INT0
8

9
     if( !thisLevel && prevLevel )  // 1 -> 0  Wechsel?
10
       sleep
11

12
     prevLevel = thisLevel;
13
  }
#1317444
Lesenswert?

Marcel H. schrieb:

> Ich würde gern meinen Merga32 über den INT0 in den Tiefschlaf schicken.
> Das ganze soll so ablaufen das der Mega sein Hauptprogramm abarbeitet
> solang ich auf INT0 high habe und sobald low anligt soll er schlafen
> gehn bis wieder high ansteht.

Geht nicht, muß genau umgekehrt sein.

Hier ein funktionierendes Beispiel:

Beitrag "Re: attiny13 aufwecken aus power down modus"


Ein funktionierendes Entprellen ist in jedem Fall erstmal die 
Grundvoraussetztung für ein funktionierendes Sleep!


Peter
Gast #1354951
Lesenswert?

> ich wollte einen einfach Drehschalter benutzen,
> muß ich diesen auch immer entprellen?

Ja!

Mechnische Kontakte prellen nun mal, leider..... und die heutigen
µPs sind schnell. (Selbst bei Ur-Ur-Alt µPs wie beim RCA1802 (kennt den 
noch jemand?) mussten schon Maßnahmen zur Entprellung getroffen werden.)
Gast #1355128
Lesenswert?

Würde es denn nicht auch ein einfaches delay von ein paar ms tuen?
Ich hab nix zeitkritisches vor.
Ich will einfach nur den Mega praktisch ausschalten aber er soll eben 
die Werte im Ram micht vergessen.
Man kann es sich wie nen einfach an/aus Schalter vorstellen mehr ist es 
garnicht.
#1355242
Lesenswert?

Marcel H. schrieb:
> Würde es denn nicht auch ein einfaches delay von ein paar ms tuen?

Die Frage ist, will man wirklich bei jedem neuen Projekt mit einer 
speziellen Entprellungslösung Zeit vergeuden?

Oder nimmt man lieber ne universelle erprobte Lösung, die wenig 
Ressourcen benötigt und wenig Seiteneffekte hat und pappt sie einfach 
rein und gut is.


Klar kann man jede Aufgabe auf viele verschiedene Arten lösen.

Aber erwarte nicht, daß andere es für Dich tun, nur weil Dir die 
vorgeschlagene funktionierende Lösung nicht gefällt.
Du mußt es schon selber tun und dann auch selber prüfen.


Peter
Gast #1355284
Lesenswert?

Ich versteh schon was du sagen willst aber es geht nicht drum obs mir 
gefällt oder nicht, ich wollte es nur so einfach wie möglich halten.
Ich bin dir sehr dankbar für deinen Vorschlag.
Mit dem entprellen habe ich jetzt auch nicht das große Problem, Lösungen 
gibt es ja genug, mir geht es viel mehr um das grundsätliche Aufwecken 
und Schlafenlegen.
Ich weiß noch immer nicht wie man dies angehen könnte.
#1355430
Lesenswert?

@  Marcel H. (Gast)

>ich nicht die Sache mit dem Dauersignal zu verarbeiten...ich bin einfach
>zu blöd

Wo ist denn das große Problem?

Lad mal das Beispiel aus dem Artikel auf deinen AVR und probiers aus.
Wie bereits gesagt muss man sich darauf einigen, dass das Aufwecken mit 
LOW passiert, geht nun mal nicht anders. Wenn der AVR wieder wach ist, 
nudelt der solange in der Hauptschleife, bis INT0 wieder auf High geht. 
Knackpunkt ist lediglich, dass man halt beim Aufwachen den INTo erstmal 
ausschalten muss, sonst gibt es Dauerinterrupts. Ist auch schon im 
Beispiel drin! Etwa so.

1
// Endlose Hauptschleife
2
 
3
    while(1) {
4

5
        if (PIND & (1<<PD2)) {  // INT0 ist wieder HIGH
6
            GICR |= (1 << INT0);            // externen Interrupt freigeben
7
 
8
            set_sleep_mode(SLEEP_MODE_PWR_DOWN);
9
            sleep_mode();                   // in den Schlafmodus wechseln
10
 
11
            // hier wachen wir wieder auf
12
            GICR &= ~(1 << INT0);           // externen Interrupt sperren
13
                                            // WICHTIG! falls der externe LOW Puls an INT0
14
            long_delay(20);                 // Entprellung
15
        }
16
 
17
        // irgendeinen Unsinn machen
18

19
        PORTD |= (1 << PD5);            // LED für eine Sekunde anschalten
20
        long_delay(1000);
21
        PORTD &= ~(1 << PD5);
22
        long_delay(1000);
23
    }
24
}

Das Entprellen passiert hier quasi durch das Aufwachen, denn das wird 
wie ein Power-On Reset verzögert. Siehe Abschnitt Morgenmuffel. Hier 
sollte man per AVR Fuses einen hohen Wert einstellen, 28ms sind 
nicht falsch. Wenn man mit dem interen RC-Oszillator arbeitet, bei dem 
solche langen Wartezeiten nicht einstellbar sind, muss man halt im 
Programm warten.

MfG
Falk
#1355992
Lesenswert?

Marcel H. schrieb:
> g nein hab ich nicht den hab ich in gedruckter Form vor mir, nur raff
> ich nicht die Sache mit dem Dauersignal zu verarbeiten...ich bin einfach
> zu blöd

Was ist ein "Dauersignal"?

Anstatt Dein Problem kunstvoll zu umschreiben, stell einfach mal den 
Code rein, den Du ausprobierst und schreib als Kommentar rein, was er 
machen soll, was Du erwartest und was falsch passiert.
Als Dateianhang natürlich!

Oder probier das Beispiel aus und frage konkret dazu, wo es es klemmt.
Der Code ist doch nicht groß, läuft ja sogar aufm ATtiny13, da sollte 
Dein ATmega32 nur drüber lachen.


Es macht wenig Sinn, immer nur um den heißen Brei zu reden.


Peter

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren