Forum: Mikrocontroller und Digitale Elektronik Einmalige Auswertung angeschlossener Tasten


von TerraTux (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Codergemeinde,

ich hab vor ein paar Tagen den Einstieg in die Welt der µC
geschafft...kommt man heut ja fast nicht mehr drumherum, und es macht
auch Spaß :)

Zu meinem Problem:

in meinem "Herumspielprogramm" wird mit jedem Schleifendurchlauf die
Funktion getkey() aufgerufen, welche wiederum die Funktion keyhit()
aufruft die einen Status zurückgibt (0 wenn keine Taste gedrückt).

Ich möchte aber, dass wenn eine Taste gedrückt wird, der Status
geliefert wird, so wie es die Funktionen auch tun. Jedoch soll dieser
Status nur einmal geliefert werden. Solange die Taste gedrückt bleibt,
soll wieder 0 zurückkommen.

Kurzum: (bei jedem Aufruf von getkey() )
0
0
1  // hier eine Taste gedrückt
0
0
0  // hier mal wieder losgelassen
1  // erneut eine Taste gedrückt
0
...

Nun hab ich hier im Forum schon einiges gelesen, z.b. 2pol. Taster,
welche einmal den Interrupt auslösen und einen Port gegen Masse ziehen
etc... Aber ich hab hier das D06x von display3000.com (die keyboard.c
ist ursprünglich auch aus mitgeliefertem Quellcode), und die Taster
sind da von Haus aus an den Port D gelegt, ergo keine HW-Interrupts)

Irgendeine Idee? So wie die Funktion getkey() derzeit aufgebaut ist,
geht es nicht, das Signal wird trotzdem solange zurückgegeben wie die
Taste gedrückt ist.

Danke & Gruß,
TT

von Sven (Gast)


Lesenswert?

Hallo,
 bin selber noch neuling und kann nur erahnen, was in deinem Code
passiert.

Aber eine universelle (evtl. nicht die eleganteste) Lösung ist:
Wenn keyhit (o.Ä.) einen Wert zurückgibt, speichert es diesen auch für
sich selbst ab. Beim nächsten Aufruf, prüft es dann ob sich der Status
Quo im Vergleich zum abgelegten Wert geändert hat. Falls Ja, gibt es
den neuen Wert aus und ändert auch den abgelegten. Falls nicht, gibt es
FALSE (o.Ä.) aus.

Habe damit mal ein Flip-Flop gebaut. Bin aber pfiffigeren Ideen gerne
aufgeschlossen.

von TerraTux (Gast)


Lesenswert?

Hi,

genau das hab ich in der Funktion getkey() ja versucht zu
bewerkstelligen. Wenn ich eine Taste drücke, liefert getkey() einen
Wert. Dieser Wert soll aber nur einmal zurückgegeben werden, egal wie
lange ich drücke. Denn während ich drücke, wird getkey() immer und
immer wieder abgefragt.

Wenn Taste gedrückt, und die 'pressed' nicht gesetzt ist, setz
'pressed' und gib den Status der Taste zurück. Halte ich gedrückt,
ändert sich ja der Status nicht (v != KEY_NONE; also größer 0) und ist
'pressed' gesetzt (wird noch gedrückt und status wurde schon
zurückgegeben) gib wieder 0 zurück. Erst wenn keyhit 0 (KEY_NONE)
liefert und 'pressed' auf 1 steht, wird das wieder auf 0 gesetzt und
er kann den nächsten Tastendruck liefern.

Aber irgendwo schein ich hier einen Denkfehler zu haben.

von Sven (Gast)


Lesenswert?

Werde mir deinen Beitrag nochmal durchlesen, wenn ich geschlafen habe.

Aber pauschal würde ich sagen der Denkfehler liegt bei dir :-)

Scherz beiseite, was ist den in 'pressed' abgelegt?

von Sebastian Heyn (Gast)


Lesenswert?

Ich löse sowas mit einer einfachen schleife nach der ausgabe. Leider
benutz ich nur BASCOM  aber das gleiche kannst du ja in c auch machen
Symbolisches beispiel

do
if getkey=keypressed then goto ausgabe
loop 'Hauptprogramm


ausgabe:
ausgabeaufdisplayfunktion
do
loop until 'keynotpressed'
return


wenn es nötig ist dass das hauptprogramm nach der ausgabe weiter lübbt
kannst du ja mit einem statusbit arbeiten

' pinb.x=0 -> taste gedrückt

do
if pinb.x=0 and status=0 then gosub ausgabe
if status=1 and pinb.x=1 then status=0
loop
end

ausgabe:
status=1 'eben wurde eine taste gedrückt
ausgabeaufdisplayfunktion
return

von Peter D. (peda)


Lesenswert?

Schau Dir das mal an (AVR-GCC-Tutorial):


http://www.mikrocontroller.net/articles/Entprellung


Peter

von TerraTux (Gast)


Lesenswert?

Hallo und Danke für die Antworten...

@Peter:
Eine Entprellung ist eigentlich genau das was ich eben nicht brauch,
denn auch dort wird der Status 'Taste gedrückt' geliefert, solange
ich den Taster auch gedrückt halte, mal unabhängig davon ob dieser auch
wirklich prellt oder nicht.

Ich hoff ich bekomm es nochmal etwas durchsichtiger erklärt...

Mit jedem durchlauf des Hauptprogramms wird getkey() aufgerufen. Drück
ich eine Taste, liefert getkey() irgendeinen Wert, welcher der
gedrückten Taste entspricht...das Programm läuft weiter. Beim nächsten
durchlauf, wird getkey() wieder aufgerufen, hier aber soll wieder 0
geliefert werden , das auch wenn die Taste noch gedrückt ist, und erst
dann wieder einen Tastenwert liefern, wenn zwischenzeitlich mal keine
Taste gedrückt war. So gesehen eigentlich nur einen Impuls...


ODER, meinst Du ich kann mit etwas umdenken diese Entprellroutinen
dafür missbrauchen?

Gruß,
TT

von Karl heinz B. (kbucheg)


Lesenswert?

> Mit jedem durchlauf des Hauptprogramms wird getkey() aufgerufen.
> Drück ich eine Taste, liefert getkey() irgendeinen Wert, welcher
> der gedrückten Taste entspricht...das Programm läuft weiter. Beim
> nächsten durchlauf, wird getkey() wieder aufgerufen, hier aber soll
> wieder 0 geliefert werden , das auch wenn die Taste noch gedrückt
> ist,

Genau das macht die
get_key_press
Funktion im angegebenen Link

von Peter D. (peda)


Lesenswert?

@TerraTux

"Eine Entprellung ist eigentlich genau das was ich eben nicht
brauch,"


Dann wärst Du aber der erste.

Entprellung braucht man immer, wenn es ums Einlesen mechanischer
Kontakte geht.

Und die Flankenerkennung braucht man auch oft, daher ist die eine
Codezeile dafür gleich mit drinne:
1
key_press |= key_state & i;    // 0->1: key press detect


Peter

von TerraTux (Gast)


Lesenswert?

Ah...also hab ich doch was falsch verstanden. :)

Gut dann werd ich mich nach Arbeit mal weiter damit beschäftigen.
Ich dank euch erstmal, und werd mich ggf. nochmal melden.

Gruß,
TT

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.