Hallo,
ich habe am Mega8 einen Taster an INT0. Bei Auslösung von INT0 wird ein
ASCI Zeichen (73) gesendet. Da der Taster nicht entprellt ist wird
dieses mehrmals gesendet. Der Versuch das Problem mit einem Timer
(Timer0) durch enable INT0 und disable Int0 zu lösen, hat zur Folge das
die Auslösung und das mehrfache Senden nur zeitlich verzögert wurde.
Hat da jemand mal einen Tipp? DANKE!
On Int0 Aktply 'InterruptRoutine für Taster
Config Int0 = Rising 'Interrupt 0 bei L/H-Flanke auslösen
Enable Int0 'Externen Interrupt 0 einschalten
On Timer0 Ontimer0 'Interrupt-Routine für Timer0-Overflow
Config Timer0 = Timer , Prescale = 1024 'Takt: Quarz/1024
Disable Timer0
Aktply: 'Int0-Routine
Printbin 73 'Ereignis via UART melden
Disable Int0
Enable Timer0
Return
'-----------------------------------------------------------------------
---
Ontimer0: 'Interrupt-Routine Timer0
Incr Tastenpause
If Tastenpause > 16 Then
Tastenpause = 0
Enable Int0
Disable Timer0
End If
Return
boerly schrieb:
> Hat da jemand mal einen Tipp? DANKE!
Ja.
Taster fragt man nicht über einen INT ab, sondern indem man in
regelmässigen Zeitabständen am Port nachsieht, ob sich etwas getan hat.
Lass mich raten.
Dein Programm ist gespickt mit Warterei :-)
-> Falscher Ansatz.
Dein µC, wenn richtig programmiert, kann die Taste in einer Sekunde
viele tausend mal abfragen. Kein Mensch kann eine Taste derart schnell
drücken und wieder loslassen.
Aber dazu darf nirgends sekundenlang gewartet werden! Genau das ist das
Um und Auf, wenn ein µC mehrere Dinge quasi gleichzeitig machen soll.
nein eigentlich nicht. An einer Stelle werden ausgänge mit waitms 500
zeitlich gesteuert und dort soll (egal wo) dann durch INT0 eine globale
Variable in einer IF Schleife den Ablauf anhalten (Pause).
Ja, ich denke es geht auch mit einem Timer, ich habe (weil vieleicht
bequemer) den Weg über INT0 und das senden über den UART in die ISR
verlagert.
>Ja, ich denke es geht auch mit einem Timer
<ironie>
Timer? Auf keinen Fall! Dann wird ja alles ganz simpel und funktioniert
auch noch einwandfrei.
</ironie>
boerly schrieb:
> Ja, ich denke es geht auch mit einem Timer, ich habe (weil vieleicht> bequemer) den Weg über INT0 und das senden über den UART in die ISR> verlagert.
Das wa auf den ersten Blick bequem aussieht, erweist sich des Öfteren
als Bumerang.
(Das UART Senden in einer ISR ist ok)
Wenn du Timer und Int0 benutzen willst, frage doch einfach in der Int0
Routine den Timer ab und ignoriere den Tastendruck (also nicht über Uart
senden), wenn nicht "genug" Zeit vergangen ist. Dann brauchst du auch
den Int0 nicht abschalten. Den Int kannst du dir aber auch sparen (siehe
weiter oben).
Ja, ;o)
habe es schon geändert und funktioniert. Danke!
Manchmal ist eben das Einfache die bessere Lösung.
Zuviel Luxus schränkt manchmal das logische Denken ein und schließt das
Logische aus.
Marco L. schrieb:
> Wenn du Timer und Int0 benutzen willst, frage doch einfach in der Int0> Routine den Timer ab und ignoriere den Tastendruck (also nicht über Uart> senden), wenn nicht "genug" Zeit vergangen ist. Dann brauchst du auch> den Int0 nicht abschalten. Den Int kannst du dir aber auch sparen (siehe> weiter oben).
Der ganze Ansatz ist zum scheitern verurteilt.
Er ignoriert zb völlig, dass Taster ja nicht nur beim Drücken Prellen
sondern auch beim Loslassen. D.h. selbst wenn er das Drücken sauber
hinbekommt, spätestens beim Loslassen taucht dasselbe Problem schon
wieder auf.
Und jede derartige Zeitsteuerung kann ich durch einen langen Tastendruck
aushebeln. Macht man aber die Zeitsteuerung so dermassen lang, dass auch
ein längerer Tastendruck kein Problem ist, dann läuft man schon wieder
in das gleiche Dilemme: Kurze Tastendrücke schnell hintereinander
funktionieren dann nicht mehr richtig.
Das Problem ist die Denkweise des
zuerst mach das
dann mach das
dann warten wir auf ein Ereignis
und dann soll das passieren
und zu guter letzt wieder alles von vorne
Das funktioniert solange gut, solange es keine asynchrone Ereignisse im
System gibt. Sobald es die aber gibt, hat man mit so einem Ansatz
praktisch immer den schwarzen Peter.
Auf einem µC muss man agieren wie ein Schachspieler der mehrere
Schachpartien simultan spielt. Reihum von einer Teilaufgabe zur nächsten
gehen und nachsehen ob es etwas zu tun gibt. Wenn ja, dann wird das
(ganz schnell) erledigt und die nächste Teilaufgabe ist drann. Aber blos
nie auf irgendetwas warten.
Karl heinz Buchegger schrieb:
> Der ganze Ansatz ist zum scheitern verurteilt.> Er ignoriert zb völlig, dass Taster ja nicht nur beim Drücken Prellen> sondern auch beim Loslassen. D.h. selbst wenn er das Drücken sauber> hinbekommt, spätestens beim Loslassen taucht dasselbe Problem schon> wieder auf.
Daran habe ich in diesem Moment noch gar nicht gedacht, aber danke für
den Hinweis. Vor dem gleichen Problem werde ich ja demnächst auch
stehen.
> Auf einem µC muss man agieren wie ein Schachspieler der mehrere> Schachpartien simultan spielt. Reihum von einer Teilaufgabe zur nächsten> gehen und nachsehen ob es etwas zu tun gibt. Wenn ja, dann wird das> (ganz schnell) erledigt und die nächste Teilaufgabe ist drann. Aber blos> nie auf irgendetwas warten.
Guter Vergleich, werd' ich dann mal in meine eigene Softwareplanung mit
einbeziehen.
Danke an Alle für die vielen Antworten.
@Karl heinz Buchegger
>Auf einem µC muss man agieren wie ein Schachspieler der mehrere>YSchachpartien simultan spielt. Reihum von einer Teilaufgabe zur nächsten>gehen und nachsehen ob es etwas zu tun gibt. Wenn ja, dann wird das>(ganz schnell) erledigt und die nächste Teilaufgabe ist drann. Aber blos>nie auf irgendetwas warten.
Ja, da kann ich nur zustimmen. Daher war der Ansatz ja auch der mit
einem INT
und dem Senden in einer ISR.
Ich habe den Taster nun über einen Timer abgefragt (alle 0,163 sec) und
es funktioniert soweit wie erwartet.
>Manchmal ist eben das Einfache die bessere Lösung.
Oder umgekehrt: "Kompliziert proggen kann jeder."
Aber Du hast es schnell verstanden, Respekt! :-)
http://de.wikipedia.org/wiki/KISS-Prinzip
- Also UART in ISR ist sowieso sehr unschön.
- Wenn du schon sowas machst, dann 'Disable Int0' gleich ganz am Anfang
der ISR.
- Wo initialisierst du eigentlich 'Tastenpause' zum Ersten Mal?
- Wie schnell läuft dein µC / wie lange ist die Tastenverzögerung
eigentlich?
- Setzen einer globalen Pause-Variable in einer ISR ist ja OK, aber was
hat das mit dem UART senden von deinem Bsp. zu tun?
Die Pause-Variable mußt du auch irgendwo abfragen, IMHO kannst da auch
gleich den Taster abfragen. Für eine simple Pausefunktion müßte das bei
2Hz Abfragefrequenz zur Not sogar ohne Entprellung funktionieren.
- siehe auch http://www.mikrocontroller.net/articles/Entprellung
by(e)
Stephan
Eine eigene Frage?
Dieser Thread ist über 17 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.