Forum: Mikrocontroller und Digitale Elektronik Mega8 Taster auf INT0 (Entpellen)


von boerly (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von boerly (Gast)


Lesenswert?

ich brauche aber den INT0, da im Programm zu jeder Zeit das Ereignis 
abgefragt werden muss.

von Karl H. (kbuchegg)


Lesenswert?

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.

von boerly (Gast)


Lesenswert?

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.

von Gast (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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)

von Marco L. (lehmi)


Lesenswert?

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

von boerly (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Marco L. (lehmi)


Lesenswert?

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.

von boerly (Gast)


Lesenswert?

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.

von Gast (Gast)


Lesenswert?

>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

von Stephan V. (orca)


Lesenswert?

- 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

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.