Hi @ all,
ich möchte über einen Taster einen Ausgang steuern jedoch zeitverzögert.
Ich drücke die Taste und der Ausgang schaltet zeitverzögert. Der Ausgang
ist solange geschaltet bis ich den Taster wieder loslasse.
Entprellen spielt momentan noch keine Rolle.
Leider funktioniert es noch nicht und ich weiss nicht an was es liegt.
Beim Drücken der Taste passiert nichts, Ausgang schaltet nicht.
Programm im Anhang
Gruss Ralph
Das ganze Program ist so wie es ist, ziemlicher Müll.
Du übernimmst dich momentan, indem du nicht zielgerichtet mit einfachen
Dingen anfängst und dich zu schwierigeren Dingen systematisch
durcharbeitest.
Konzepte, die du anscheinend nicht verstanden hast
* Unterprogramme
* Interrupt Service Handler
* wie man mit Timern grundsätzlich arbeitet
* Das Konzept einer Hauptschleife
> Beim Drücken der Taste passiert nichts, Ausgang schaltet nicht.
Kannst du einen Ausgang abhängig vom einem Taster ohne irgendewelchen
sonstigen Schnickschnack schalten? Ohne Timer, ohne sonst irgend etwas.
Einfach nur: Taster gedrückt -> Ausgang geschaltet; Taster nicht
gedrückt -> Ausgang nicht geschaltet.
Ja das hab ich schon versucht das geht.
Wie arbeitet man denn grundsätzlich mit einem Timer?
Das Beispiel im Tutorial ist doch auch ziemlich einfach gehalten und
nach dem hab ich es versucht aufzubauen.
Interner Takt 1Mhz
Vorteiler 1024
macht 3,8 Overflows / Sekunde
Wenn man dann noch ein Register entsprechend hochtzählt dann komme ich
ja auf meine paar Sekunden Verzögerungszeit. (noch nicht im Code
enthalten)
Gruss Ralph
Hi
>Wie arbeitet man denn grundsätzlich mit einem Timer?
Das ist nicht dein primäres Problem.
Z.B. Interrupt: Du löst einen Interrupt aus und springst von dort zurück
ins Hauptprogramm. *Das geht nicht.* Der Rücksprung aus einer ISR
erfolgt grundsätzlich mit RETI. Und zwar an die Stelle, an der dein
Programm unterbrochen wurde. Beim Sprung in eine Interruptroutine wird
nämlich die Rückkehradresse auf dem Stack gespeichert und mit 'reti'
wieder zurückgeholt. Ein 'rjmp' macht das nicht, und du produzierst
unweigerlich einen Stacküberlauf, der dein Programm ins Nirvana schickt.
In der ISR muss das SREG und die veränderten Register, soweit nicht
gewollt, mit 'push' gesichert und mit 'pop' restauriert werden.
MfG Spess
spess53 schrieb:
> Hi>>>Wie arbeitet man denn grundsätzlich mit einem Timer?>> Das ist nicht dein primäres Problem.>> Z.B. Interrupt: Du löst einen Interrupt aus und springst von dort zurück> ins Hauptprogramm.
Wenns nur das wäre.
Da wird ge-callt und ge-rjmp-t, auf Teufel komm raus. Quer durch die
Gegend.
Hi
>Wenns nur das wäre.>Da wird ge-callt und ge-rjmp-t, auf Teufel komm raus. Quer durch die>Gegend.
Ich weiss. Habe nur keine Lust einen Roman zu verfassen.
MfG Spess
Was sucht das wdr da? Damit sind deine Interrupt-Vektoren alle um eins
verschoben.
Ansonsten ist, wie Karl Heinz schon schreibt, die ganze Struktur vom
Programm so nix, bzw. gar nicht wirklich vorhanden. Du springst kreuz
und quer in der Gegend rum, und rennst aus deinen Funktionen am Ende
einfach raus in den dahinterliegenden Code. Und dann wartest du in der
ISR noch in einer Schleife auf den Taster.
Auf die Gefahr hin mich hier unbeliebt zu machen hier der nächste
Versuch.
Funktionieren tut es jetzt schon. Aber formlich bestimmt nicht das
Wahre.
Bin im ISR direkt auf Ausgang gesprungen. Darf man das in dem Fall oder
sollte man das anders lösen?
Hi
>Funktionieren tut es jetzt schon. Aber formlich bestimmt nicht das>Wahre.
Was funktioniert? Früher oder später, aber eher früher, sitzt dein
Programm bei:
loop: rjmp loop
fest. Und das wars.
Eine 'mainloop' sollte so aussehen:
mainloop: .....
.....
rjmp mainloop
MfG Spess
Mhh ich hab Taster gedrückt nach ca 5sek wird Ausgang gsetzt.
Lass ich Taster los ist Ausgang nichtmehr gesetzt.
Hab das ganze 5x wiederholt ging ohne Probleme.
> Auf die Gefahr hin mich hier unbeliebt zu machen hier der nächste> Versuch.
Keine Sorge.
> Funktionieren tut es jetzt schon. Aber formlich bestimmt nicht das> Wahre.
Immerhin ist es jetzt strukturmäßig schon deutlich besser. Du wartest
allerdings immer noch in der ISR. Deine mainloop ist eigentlich auch
keine loop, denn sie wird nur einmal ausgeführt.
Übrigens: das cli und sei in der ISR kannst du dir sparen. Das macht der
Prozessor schon selbst für dich.
> Bin im ISR direkt auf Ausgang gesprungen. Darf man das in dem Fall oder> sollte man das anders lösen?
Das ist schon ok. Dieses Label gehört von der Ausführungslogik gesehen
zur ISR. Du mußt nur darauf achten, daß die ISR, wenn sie fertig ist,
ein reti ausführt, und das ist bei dir jetzt der Fall.
Hi
>Mhh ich hab Taster gedrückt nach ca 5sek wird Ausgang gsetzt.>Lass ich Taster los ist Ausgang nichtmehr gesetzt.>Hab das ganze 5x wiederholt ging ohne Probleme.AVR-Studio-Simulator und ich sind der gleichen Meinung. Erkläre mal, wie
der Controller aus der Schleife wieder herauskommen soll.
Oder ist das nicht dein aktuelles Programm?
MfG Spess
> Erkläre mal, wie der Controller aus der Schleife wieder herauskommen> soll.
Bei der Programmstruktur muß er das gar nicht, weil alles in der ISR
abgehandelt wird.
Rolf Magnus schrieb:
>> Erkläre mal, wie der Controller aus der Schleife wieder herauskommen>> soll.>> Bei der Programmstruktur muß er das gar nicht, weil alles in der ISR> abgehandelt wird.
Bis auf das Niederdrücken des Tasters.
So wie ich das sehe, läuft das Programm nach dem ersten Tastendruck so
weiter:
Alle 40 Timeroverflows wird
* der Port auf 1 gesetzt
* darauf gewartet, dass der Taster nicht gedrückt ist
* der Prt wieder auf 0 gesetzt
Unter der Annahme, dass die 40 Overflows in etwa 5 Sekunden sind, müsste
man daher am Oszi bei nicht gedrückten Taster (nach dem ersten
Tastendruck) sehen:
alle 5 Sekunden gibt es einen kurzen Spike am Port B
Beim ersten mal Tastendrücken wird die Verzögerungszeit sogar
einigermassen stimmen. Aber bei den weiteren Tastendrücken ist es
Zufall, ob die Verzögerungszeit eingehalten wird oder nicht.
Hauptsächlich deshalb, weil die ISR ja weiter brav bis 40 zählt und ihr
das völlig egal ist, ob der Taster gedrückt wurde oder nicht.
Hi
>Bei der Programmstruktur muß er das gar nicht, weil alles in der ISR>abgehandelt wird.
Dort wartet es nur auf das Loslassen der Taste. Und danach läuft das
Programm in die loop-Schleife.
MfG Spess
Erstmal danke. Es klingt aufjedenfall plausibel. Das heisst ich muss
wenn ich bei "Ausgang" bin den Interrupt deaktivieren und deaktiviert
lassen und am Ende bei Warten wieder hoch zum Mainloop wo der Taster
wieder eingelesen wird?
Dann hab ich aber zum Schluss kein reti durchgeführt. Muss ich nach dem
"Ausgang" das TOIE0 Bit im TIMSK Register wieder auf 0 setzen?
Gruss Ralph