Hi Community,
wie ich Tasten einlese weiß ich, mir geht es hier um die verschiedenen
Möglichkeiten, welche Methoden sind für welche Anwendung geeignet.
Ich möchte ein Programm erstellen, dass nach einer Initialisierungs- und
Einstellphase hauptsächlich nur noch auf Tastendrücke reagiert.
Ich habe mir bereits die verschiedenen Beispielcodes zum
Tastenentprellen etc. durchgelesen und auch großteils verstanden.
An dieser Stelle schonmal ein Dankeschön :)
Nun zur eigentlichen Frage:
In meinem Projekt soll auf einen Tastendruck reagiert werden:
Eine Funktion F1 soll direkt nach der Betätigung von einem Taster T1, es
soll auch schon ein Antippen ausreichen, ausgeführt werden.
Wann T1 losgelassen wird bzw. wie lang T1 gehalten ist mir egal.
Dauert jetzt F1 länger, wie T1 prellt, muuss ich ja theoretisch nicht
entprellen oder?
Da ich jetzt nicht vorraussagen kann, wann T1 betätigt wird, habe ich
überlegt das ganze über Interrupts zu steuern.
Sprich es soll auf eine steigende Flanke an T1 gewartet werden. Nun habe
ich aber gelesen, dass ein Interrupt nicht über einen Taster ausgelöst
werden soll, da durch das prellen der Interrupt ja öfter ausgeführt
werden würde.
Gleiche Frage wie oben:
Wenn F1 länger dauert, wie T1 prellt und während F1 keine Interrupts
zulässig sind, ist es doch unkritisch, den Interrupt auf T1 zu legen?
Sollte ich hier falsch liegen, wie sollte ich dann auf T1 prüfen, ob
dieser betätigt wurde?
Im Anhang habe ich mal eine Zeichnung, welche die Zeitabhänigkeiten
exemplarisch darstellen soll.
Ich hoffe ich konnte meine Frage deutlich darstellen und hoffe auf ein
paar Tipps, wie ich die Sache am besten angehe.
Ich möchte keine Codes, nur eine Erklärung wie und warum ich auf ein
solches Tasterereignis reagieren soll.
Danke schonmal für eure Hilfe
MC-Anfänger
MC-Anfänger schrieb:> wie ich Tasten einlese weiß ich, mir geht es hier um die verschiedenen> Möglichkeiten, welche Methoden sind für welche Anwendung geeignet.>
Ist ganz einfach.
Die brauchst eigentlich nur die Danegger Entprellung aus dem Wiki
Artikel Entprellung.
Die kann alles was man in der Praxis braucht.
> Da ich jetzt nicht vorraussagen kann, wann T1 betätigt wird, habe ich> überlegt das ganze über Interrupts zu steuern.
Timer Interrupt, wie in der Danegger Entprellung
> Sollte ich hier falsch liegen, wie sollte ich dann auf T1 prüfen, ob> dieser betätigt wurde?
Du überlässt das der Danegger Entprellung.
Alles was du dazu brauchst, ist ein Timer, in dessen ISR alle paar
Millisekunden nachgesehen wird, ob sich was an den Tastern getan hat.
In einem Wort: Danegger Entprellung
> Ich möchte keine Codes, nur eine Erklärung wie und warum ich auf ein> solches Tasterereignis reagieren soll.
Auf jeden Fall nicht mit einem externen Interrupt
PS: auch in zeitlich kritischen Programmen benutzt man die Danegger
Entprellung. Warum?
Weil sie fast keine Rechenzeit verbraucht und gut funktioniert. Und kein
Mansch kann sagen, ob die Reaktion des Programms ~30 Millisekunden nach
dem Tastendruck kommt oder schon früher. Bei Tastendrücken bewegen wir
uns im Bereich von Zehntelsekunden, nicht Millisekunden. Schon
Millisekunden sind für einen µC eine Zehntel Ewigkeit, Zehntelsekunden
sind dagegen Zeitalter.
MC-Anfänger schrieb:> welche Methoden sind für welche Anwendung geeignet.
Ich nehme immer nur eine Methode und die war bisher für ausnahmslos jede
Anwendung geeignet.
Daher sehe ich keinen Sinn darin, sich den Kopf zu zerbrechen, ob man
für manche Anwendungen auch ne andere Methode nehmen könnte. Man sollte
unnütze Arbeit ruhig vermeiden.
Ob Entprellen, Flanke erkennen, Lang-/Kurzdruck, Repeat, 2 Tasten
gleichzeitig ..., ich will mir da keinen Kopp machen müssen, ich rufe
einfach die entsprechenden Funktionen auf und gut is.
Peter
Die Kunst beim Programmieren ist nicht, jedesmal neue auf die Anwendung
zugeschnittene Speziallösungen zu schaffen, sondern zu abstrahieren.
Man versucht einen Aufgabe so universell wie möglich zu lösen, damit man
dann die Lösung beim nächsten Projekt einfach übernehmen kann.
Beim Tastenabfragen ist z.B. Entprellen und Flanke erkennen immer nötig.
Zusätzlich sollten keine Wartezeiten das Programm blockieren. In vielen
Fällen laufen ja noch andere Sachen neben der Tastenabfrage. Und wenn
mal nicht, lohnt sich trotzdem keine Speziallösung.
Man muß auch daran denken, daß Programme eine sehr hohe Tendenz haben,
später mal erweitert zu werden.
Peter
Hi,
das ging ja schnell :)
Das Argument nach Möglichkeit universelle Lösungen zu erzeugen klingt
sehr überzeugend.
Also werde ich mir mal Ihren Code zur Entprellung nochmal genauer
ansehen.
Danke schonmal für die Antworten.
Gruß MC-Anfänger
Hi,
ich hab jetzt mal eine Kleinigkeit programmiert, leider funktioniert das
Ganze nicht so richtig :(
Ich habe das Evaulation-Board von Pollin und einen ATMega16.
Zum Test habe ich das Programm erstellt und auf den Device geschoben,
jedoch reagiert dieser leider nicht ganz wie erwartet...
Hier mal der Code (Wie von euch empfohlen den von Peter Dannegger, aber
etwas abgewandelt)
// check if a key has been pressed. Each pressed key is reported
56
// only once
57
//
58
uint8_tget_key_press(uint8_tkey_mask)
59
{
60
cli();// read and clear atomic
61
key_mask&=key_press;// read key(s)
62
key_press^=key_mask;// clear key(s)
63
sei();
64
returnkey_mask;
65
}
66
67
68
intmain(void)
69
{
70
KEY_DDR&=~ALL_KEYS;// konfigure key port for input
71
KEY_PORT|=ALL_KEYS;// and turn on pull up resistors
72
73
TCCR0=(1<<CS02)|(1<<CS00);// divide by 1024
74
TIMSK|=1<<TOIE0;// enable timer interrupt
75
76
LED_PORT=0x60;
77
LED_DDR=0x60;
78
79
sei();
80
81
while(1)
82
{
83
if(get_key_press(1<<KEY2))
84
LED_PORT^=(1<<LED0);
85
if(get_key_press(1<<KEY1))
86
LED_PORT^=(1<<LED1);
87
if(get_key_press(1<<KEY0))
88
LED_PORT^=0x60;
89
}
90
}
Ich würde erwarten, dass wenn ich
- KEY2 drücke, LED0 an/aus geschaltet wird
- KEY1 drücke, LED1 an/aus geschaltet wird
- KEY0 drücke, LED0/LED1 an/aus geschaltet wird
Jedoch tut sich irgendwie nichts...
Habe ich einen Fehler gemacht bzw. gibt es ein Problem, da LEDs und
Taster auf einem Port liegen?
Danke schonmal für Eure Hilfe
MC-Anfänger
MC-Anfänger schrieb:> Ich habe das Evaulation-Board von Pollin und einen ATMega16.
Hast du das Board schon modifiziert?
Die Tasteranschaltung ist bei dem Board schlecht gemacht.
Ich such schon die ganze Zeit nach dem Artikel dazu, aber ich finde ihn
nicht mehr.
In der Originalbeschaltung sind diese Taster, entgegen üblichen
Gepflogenheiten 'high active' verschaltet.
Dreh dazu die Zeile
i = key_state ^ ~KEY_PIN; // key changed ?
um auf
i = key_state ^ KEY_PIN; // key changed ?
Damit sollte sich dann zumindest etwas tun.
Danke für die schnelle Antwort, jetzt tut sich tatsächlich was, leider
wird nicht jeder Tastendruck erkannt...
Das hängt mit dem Board zusammen? -> Ich habe daran nichts modifiziert,
aber ich werde mich mal auf die Suche nach dem Beitrag begeben
Auf die Pullupwiderstände muss ich zugeben, habe ich nicht geachtet.
Aber da das Board Active-High ist, müsste ich die internen ja eigentlich
abschalten oder?
In der main also anstatt:
KEY_PORT |= ALL_KEYS;
Das hier einsetzen?
KEY_PORT &= ~ALL_KEYS;
MC-Anfänger schrieb:> Danke für die schnelle Antwort, jetzt tut sich tatsächlich was, leider> wird nicht jeder Tastendruck erkannt...> Das hängt mit dem Board zusammen? -> Ich habe daran nichts modifiziert,> aber ich werde mich mal auf die Suche nach dem Beitrag begeben
Im wesentlichen geht es darum, bei jedem Taster den C und den R
auszubauen und eine kleine Modifikation zu machen, so dass die Taster
gegen Masse schalten und nicht mehr gegen Vcc
> Auf die Pullupwiderstände muss ich zugeben, habe ich nicht geachtet.> Aber da das Board Active-High ist, müsste ich die internen ja eigentlich> abschalten oder?
Ja.
> In der main also anstatt:> KEY_PORT |= ALL_KEYS;>> Das hier einsetzen?> KEY_PORT &= ~ALL_KEYS;
Im Prinzip ja. Da aber die Pullups beim Einschalten sowieso aus sind,
kannst du das auch komplett streichen, schadet aber auch nicht.
Hi
Mein Tipp: Modifizier nicht am Board. Da du mit 3 Tastern auf Dauer
sowieso nicht auskommst, kauf dir ein Steckbrett, such dir ein 40pol.
altes Festplattenkabel und löte auf eine Seite eine 40 Pol. Fassung
drauf. Diese steckst du aufs Steckbrett und machst ein paar Rangierungen
auf zugängliche Kontakte. So brauchst du dir die Platine nicht versauen
und kannst alles mögliche an den Controller ranbasteln......
Übrigends gibt es auch Quetschstecker, ähnlich einer 40 pol. Fassung.
Ich hatte einen in meiner Kramkiste, weiß aber nicht mehr, wo ich den
mal gekauft hab.
Gruß oldmax
Martin Vogel schrieb:> Mein Tipp: Modifizier nicht am Board. Da du mit 3 Tastern auf Dauer> sowieso nicht auskommst, kauf dir ein Steckbrett, such dir ein 40pol.> altes Festplattenkabel und löte auf eine Seite eine 40 Pol. Fassung> drauf.
Das kann ich nur unterstreichen.
So ein Verbindungskabel zu einem Steckbrett ist Gold wert.
Ich habe das auch mit einem Flachbandkabel auf einer IC-Fassung gemacht.
Allerdings brechen mit der Zeit gerne einzelne Adern direkt an der
Lötung beim IC-Sockel ab. Meine Lösung: Das Kabelende, Lötung, IC-Sockel
schön mit Heisskleber verpappen, so dass das Kabelende in Bezug zum
Sockel mechanisch fixiert ist und die Lötung nicht mehr mechanisch
beansprucht wird. Seitdem ich das gemacht habe, bricht da nix mehr.
Hi,
danke für die Tipps, Kabel hab ich mir schon besorgt und vorbereitet :-)
Steckbrett wird dann demnächst folgen. Bis dahin baue ich mir mal eine
'schwebende' Schaltung auf.
Ich hoffe das ganze klappt.
Sollte ja, da am Code ja anscheinend alles zu stimmen scheint.
Letzte Änderungen:
- Interne Pullups deaktiviert
- Abfrage für aktive high geändert
Wird für den 'Schwebeversuch' natürlch passend wieder geändert.
Danke nochmal für eure Tipps/Hilfe
Gruß
MC-Anfänger