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
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!!!
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
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
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
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.
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
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
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?
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
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!!!
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.
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