Forum: Mikrocontroller und Digitale Elektronik Timer funktioniert nicht


von RevolT3c (Gast)


Angehängte Dateien:

Lesenswert?

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

von RevolT3c (Gast)


Angehängte Dateien:

Lesenswert?

Edit:// hier aktuelle Version

von Karl H. (kbuchegg)


Lesenswert?

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.

von RevolT3c (Gast)


Lesenswert?

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

von spess53 (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von spess53 (Gast)


Lesenswert?

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

von Rolf Magnus (Gast)


Lesenswert?

Was soll denn das sein?
1
begin:
2
  wdr
3
  rjmp  main  ; 1    POWER ON RESET

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.

von RevolT3c (Gast)


Angehängte Dateien:

Lesenswert?

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?

von spess53 (Gast)


Lesenswert?

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

von RevolT3c (Gast)


Lesenswert?

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.

von Rolf Magnus (Gast)


Lesenswert?

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

von spess53 (Gast)


Lesenswert?

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

von Rolf Magnus (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

RevolT3c schrieb:

> Hab das ganze 5x wiederholt ging ohne Probleme.

Ohne zwischendurch den Reset Taster zu benutzen?
Erstaunlich!

von Karl H. (kbuchegg)


Lesenswert?

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.

von spess53 (Gast)


Lesenswert?

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

von RevolT3c (Gast)


Lesenswert?

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

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.