Forum: Mikrocontroller und Digitale Elektronik Power Down Sleep Mode


von Izoard (Gast)


Angehängte Dateien:

Lesenswert?

Hallo

Ich möchte mittels einem Taster mein AT90S8515 in den Power Down Modus 
schicken!
Wenn er Schläft, soll Pin 2 an PortC auf null gesetzt sein und sonst 
soll dieser Pin auf eins sein!
Um den Prozessor zu wecken muss ich ja ein Low Signal geben, welches 
länger als ein Reset Signal ist. Ich setzte darum den Interrupt auf Low 
Level erkennung!
Nun testete ich mein Programm (siehe Anhang) Wenn ich nun ca. 1 Sekunde 
auf mein Taster drücke, geht er schlafen! Wenn ich wieder eine Sekunde 
auf mein Taster drücke erwacht mein Prozessor nicht immer! Es kommt vor, 
dass ich über 10 sekunden lange auf dem Taster bleiben muss!
Kann es sein, dass man den uP nicht schnell nacheinander aus und ein 
(schlafen und wecken) schalten kann????

Oder habe ich im Source einen Fehler???

Vielen Dank für die Hilfe

IZoard

von Izoard (Gast)


Lesenswert?

Das Reset Signal ist ja ca 11ms darum habe ich rasch ein Low Signal an 
meinem Interrupt 0, welches länger als das Reset Signal ist, darum 
verstehe ich nicht, wieso ich teilweise so lange ein LOW Signal anlegen 
muss, damit er wieder erwacht!!!

von Peter D. (peda)


Lesenswert?

Hi Izoard,

Wenn ich das richtig verstehe, willst Du einen Flip-Flop bauen.

Dann laß doch den Power Down Mode weg und bringe erstmal den Flip-Flop 
zum laufen.

Die meisten Fehler werden beim Entprellen der Tasten gemacht. Und das 
bewirkt dann, daß eine Flip-Flop scheinbar völlig unkontrolliert 
umschaltet.

Zum Entprellen habe ich hier was geschrieben:

http://www.specs.de/~danni/appl/soft/keyscan/index.htm


Die Messung, ob mindestens 1s gedrückt wurde, muß dann nach dem 
Entprellen erfolgen.


Beim Power Down gibt es noch zu beachten, daß wenn die Taste kürzer als 
16ms gedrückt wurde der µC zwar aufwachen kann, aber nicht den Interrupt 
ausführt und direkt nach dem Sleep weitermacht.


Peter

von Oliver K. (Gast)


Lesenswert?

Hallo Izoard,
beim Durchgehen Deines Quellcodes ist mir aufgefallen, dass Du beim 
Eintritt in die Interruptroutine nicht das Statusregister gesichert 
hast. Mach das bitte, sonst veränderst Du in der Interruptroutine die 
Statusflags und Dein Hauptprogramm kommst so ins Schleudern.

int0_handler:
in    rSREG_BAK, SREG
...
out   SREG, rSREG_BAK
reti


Grüße
Oliver

von Izoard (Gast)


Angehängte Dateien:

Lesenswert?

Vielen Dank schon mal für die Hilfe, ich habe nun beide 
Verbesserungsvorschläge gemacht!!!
Mir ist noch aufgefallen, beim durchsteppen im AVR Studio, springt er 
vom "reti" des "noflag" labels zum "int0_hander" - label! Ich finde den 
Fehler jedoch nicht!!!
Hier nochmals die Interrupt Routine:



int0_handler:
  in  sreg_bak, sreg
  lds  mpr, $0072    ;Wenn Flag gelöscht ist,
  cpi  mpr, 0      ;springe zu Noflag
  breq  noflag      ;
        ldi  mpr, 0      ;Flag löschen
  sts  $0072, mpr    ;
  out  sreg, sreg_bak
  reti        ;Retour aus Interrupt

noflag:  ldi  mpr, 1      ;Flag setzen                 sts  $0072, mpr 
;
  out  sreg, sreg_bak
  reti        ;Retour aus Interrupt



Ich hoffe jemand sieht den Fehler...

IZAORDS

von mikki merten (Gast)


Lesenswert?

Und wie geht's nach dem SLEEP Befehl weiter ???

von Izoard (Gast)


Lesenswert?

Nach dem SLEEP Befehl muss ja dieses Low Signal den uC wieder wecken und 
dann wird der Interrupt ausgeführt!!! Habe ich gedacht....
Stimmt das????

von mikki merten (Gast)


Lesenswert?

Im Prinzip ja und wohin kehrt er dann zurück ???

von Izoard (Gast)


Lesenswert?

Nach dem Interrupt??? solllte er wieder in den loop zurückkehren!!
Wie muss man das programmmieren???

von mikki merten (Gast)


Lesenswert?

dann solltest du hinter dem SLEEP Befehl folgende Befehle einfügen:
NOP
NOP
NOP
NOP
RJMP LOOP
Die 4 NOP Befehle sind nur Platzhalter, da die AVR Prozessoren ein paar 
Taktzyklen (siehe Datenblatt) brauchen um die Interrupt Flags nach dem 
Aufwachen zu aktualisieren.

von Izoard (Gast)


Lesenswert?

Hey cool vielen Dank! jetzt funktionierts :-))))

von Izoard (Gast)


Angehängte Dateien:

Lesenswert?

leider funktionierts nur richtig im Simulator!! als ich das Programm 
real testen wollte, war wieder das selbe Phänomen, wie früher, nämlich 
das der uP nicht bei jedem Tastendruck aufwacht! und beim abschalten, 
schaltet er manchmal, nach dem ich die Taste losgelassen habe wieder 
ein! wirklich komisch!
der Taster habe ich mit einem Verzögerungsglied und einem Schmittrigger 
entprellt!

Izoard

von Oliver K. (Gast)


Lesenswert?

Also ich habe mal Deinen Quellcode runtergeladen und in das AVR-Studio 
integriert. Ein paar Mal durchgestept um mir ein Bild zu machen. Ich 
glaube an dem ganzen Konzept muss noch gearbeitet werden.

Der Interrupt ist Pegel-getriggert, das heißt, so lange ein low-Pegel 
anliegt, wird jedesmal der Interrupt sofort wieder ausgelöst, sobald er 
durch ein reti verlassen wurde.

Ist das so gewollt?

Oliver

von Izoard (Gast)


Lesenswert?

zum durchsteppen habe ich den Interrupt auf Flanke-getriggert, damit ich 
das programm überprüfen konnte! Jedoch muss ich den Interrupt Pegel 
triggern, damit mein uP aus dem Power Down Modus erwacht! Oder habe ich 
das falsch verstanden?

von Oliver K. (Gast)


Lesenswert?

Nun, um aus dem Sleep-Modus wieder aufzuwachen muss der Interrupt schon 
pegelgetriggert sein. Das Problem ist nur, dass der Interrupt ständig 
erneut aufgerufen wird und so die Abarbeitung des restlichen Codes 
verzögert.

Man müsste den Interrupt, nachdem er das erste Mal aufgerufen wurde, für 
eine gewisse Zeit sperren.

Oliver

von Izoard (Gast)


Lesenswert?

aber der interrupt wird doch nicht ständig auferufen, wenn ich ein 
Taster, der inaktiv den Interrupt eingang auf High zieht und aktiv den 
Eingang auf low setzt!!!

von Oliver K. (Gast)


Lesenswert?

Ich nehme an, Du verwendest das STK500(200)-Board. Ich bin mit dieser 
negativen Logik und den Tastern immer auf Kriegsfuss.
Also, wenn Du den Taster runterdrückst, dann hast Du einen Low-Pegel. 
Und bei einem Low-Pegel wird die Interruptroutine ständig aufgerufen, so 
daß der restliche Code zu diesem Zeitpunkt fast gar nicht mehr zur 
Ausführung kommt.
Ich nehme an, daher rührt auch die zeitlich Verzögerung der 
Kontrollerreaktion, die Du schon weiter oben beschrieben hast.

von Izoard (Gast)


Lesenswert?

Ohhh ja, du hast recht, vielen Dank!
Ich habe nun eine WArteschleife am Anfang der Interrupt Routine gesetzt 
und nun funktioniert's :-)
Vielen Dank nochmals

IZOARDS

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
Noch kein Account? Hier anmelden.