PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Bei Taster auf Flanke reagieren bzw. wie Softkeys sperren



elcapitano
25.03.2008, 21:31
Hallo zusammen,

ich bin gerade dabei mir mit Hilfe eines LCDs und 4 "Softkeys" darunter ein Menü aufzubauen. Dabei sind die 4 Taster so unter dem Display angeordnet, dass ich auf dem 4x20er Display in der untersten Zeile jeweils die Funktion der Taste in dem jweiligen Untermenü angezeigt bekomme.

Derzeit frage ich die Tasten mit debounce ab. Das entprellt zwar schön, hat aber den Nachteil, dass dass auf dem Zustand der Taste geschaut wird und nicht auf die Zustandsänderung.

Folgendes Problem ergibt sich:

Beispiel:
Ich bin im Hauptmenü, drücke auf "Taste 4" um ins Untermenü 4 zu kommen. Dort ist aber die Taste 4 schon wieder mit der "Unter-Untermenü 4" Funktion belegt. Da das Programm ja viel schneller durchläuft als ich die Taste wieder loslassen kann "rausche" ich automatisch ins zweite Untermenü ohne eine Chance zu haben ins erste zu kommen.

Ich sehe jetzt zwei Möglichkeiten das Problem zu lösen:

1.) Verwendung von Interrupts und Auswerten der Flanke des Signals

Problem:

* begrenzte Anzahl der Int
* IMHO kann ich den Interruptvektor nur global genau ein mal festlegen. Somit könnte ich dann beim Drücken ein und der selben Taste nicht mehrer Funktionen anspringen

2.) Beim ersten Schleifendurchlauf eine Variable setzen, diese erst wieder zuücknehmen (also Null setzen) wenn die Taste zwischenzeitlich mal null war und dann die Schleife erst verlassen wenn die Variable wieder zurückgesetzt wurde. So ganz hab ich es selbst noch nicht ausgetüftelt...



...gibts da einen Standardweg für solche Probleme? Wie kann ich es angehen? Wer kann mir Tipps geben???

Viele Grüße
ElCapitano

python_rocks
25.03.2008, 22:07
Derzeit frage ich die Tasten mit debounce ab.
Hallo ElCapitano!

Debounce verhält sich nicht so wie du geschildert hast. Debounce reagiert auf eine Änderung. Aber nur einmal. Erst wenn die Taste zwischenzeitlich wieder losgelassen wurde, wird der nächste Tastendruck registriert.

Irgendetwas stimmt also in deinem Programm nicht. Es darf nur ein Tastendruck erkannt werden.

mfg
Gerold
:-)

Feratu
25.03.2008, 22:08
Hi
Habe ein ähnliches Problem wie du. Ist zwar nicht die schönste lösung aber sie funktioniert super ;P



'-------------------------------------------------------------------------------
'------- Tastatur Auswertung
'-------------------------------------------------------------------------------
Tast_a:
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
Dim Freigabe As Bit
Freigabe = 0
Tsta = 13
'-------------------------------------------------------------------------------
Do
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
Do
'-------------------------------------------------------------------------------
Tsta = 13
If Pinc.7 = 1 Then

Tsta = 1
End If
If Pinc.6 = 1 Then
Tsta = 2
End If
If Pinc.5 = 1 Then
Tsta = 3
End If
'-------------------------------------------------------------------------------
Porta.7 = 1
'-------------------------------------------------------------------------------
If Pinc.3 = 1 Then
Tsta = 4
End If
If Pinc.2 = 1 Then
Tsta = 7
End If
If Pinc.1 = 1 Then
Tsta = 10
End If
'-------------------------------------------------------------------------------
Porta.7 = 0
'-------------------------------------------------------------------------------
Portc.0 = 1
'-------------------------------------------------------------------------------
If Pinc.3 = 1 Then
Tsta = 5
End If
If Pinc.2 = 1 Then
Tsta = 8
End If
If Pinc.1 = 1 Then
Tsta = 11
End If
'-------------------------------------------------------------------------------
Portc.0 = 0
'-------------------------------------------------------------------------------
Portc.4 = 1
'-------------------------------------------------------------------------------
If Pinc.3 = 1 Then
Tsta = 6
End If
If Pinc.2 = 1 Then
Tsta = 9
End If
If Pinc.1 = 1 Then
Tsta = 12
End If
'-------------------------------------------------------------------------------
Portc.4 = 0 'PC5
Portc.0 = 0 'PC6
Porta.7 = 0 'PC7
'-------------------------------------------------------------------------------
Loop Until Tsta = 13 Or Freigabe = 1
Freigabe = 1
'-------------------------------------------------------------------------------
If Random > 6 Then Random = 1
Loop Until Tsta < 13
Tstaa = Tsta
Return

Man muss dazu sagen das ich dabei ein Tastenfeld mit 12 Tasten ansteuere . und somit der Wert nciht über 13 gehn kann.
Hab erst im nachinein rausgefunden das es schon so eine auswertung gibt aber die version gefällt mir besser ^^

Im grunde ist das deine Idee mit der Variable die erst zurückgesetzt wird wenn man die Taste loslässt.

in einer durchlaufenden Schleife sähe das in etwa so aus:


'-------------------------------------------------------------------------------
'------- Hauptschleife
'-------------------------------------------------------------------------------
Do
'-------------------------------------------------------------------------------
'Tastenauswertung
'-------------------------------------------------------------------------------
Taste = 13
If Pinc.7 = 1 Then
Taste = 1
End If
If Pinc.6 = 1 Then
Taste = 2
End If
If Pinc.5 = 1 Then
Taste = 3
End If
'-------------------------------------------------------------------------------
Porta.7 = 1
'-------------------------------------------------------------------------------
If Pinc.3 = 1 Then
Taste = 4
End If
If Pinc.2 = 1 Then
Taste = 7
End If
If Pinc.1 = 1 Then
Taste = 10
End If
'-------------------------------------------------------------------------------
Porta.7 = 0
'-------------------------------------------------------------------------------
Portc.0 = 1
'-------------------------------------------------------------------------------
If Pinc.3 = 1 Then
Taste = 5
End If
If Pinc.2 = 1 Then
Taste = 8
End If
If Pinc.1 = 1 Then
Taste = 11
End If
'-------------------------------------------------------------------------------
Portc.0 = 0
'-------------------------------------------------------------------------------
Portc.4 = 1
'-------------------------------------------------------------------------------
If Pinc.3 = 1 Then
Taste = 6
End If
If Pinc.2 = 1 Then
Taste = 9
End If
If Pinc.1 = 1 Then
Taste = 12
End If
'-------------------------------------------------------------------------------
Portc.4 = 0 'PC5
Portc.0 = 0 'PC6
Porta.7 = 0 'PC7
'-------------------------------------------------------------------------------
'------- Tastenabfrage zu Ende folgt: Tastensperre für Prellfilter
If Taste = 13 Then Taste_freigabe = 1 'Setzt die Freigabe auf eins wenn keine Taste gedrückt wurde sprich Taste = 13
If Taste_freigabe = 0 Then 'Wenn Freigabe 0 dann also wenn die Zahl zuvor nicht 13 war setzte Taste auf 13
Taste = 13
Else 'Wenn Taste Freigabe = 1 dann übernehme die anstehende Zahl in die Ausgabe
Taste_ausgabe = Taste 'Wert Übergabe
End If
If Taste <> 13 Then 'Wenn Taste ist nicht 13 dann setzte Freigabe wieder auf 0
Taste_freigabe = 0 'Freigabe für Tasten 0
End If
'-------------------------------------------------------------------------------
'------- Tastensperre Ende
'------- Starte Menu Teil
'-------------------------------------------------------------------------------
blablabla hier kommt das programm


'-------------------------------------------------------------------------------
'------- Loop Ende Hauptschleife
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
Ende_schleife:
Taste_ausgabe = 13
Loop




So hoffe mal ich hab dir weiter geholfen
mfg

Fera ;P

elcapitano
25.03.2008, 22:26
@python_rocks

Hmmm...ich hab dieses Problem bisher nur in der Simulatuion gehabt (mein großes Display fehlt mir derzeit) - vielleicht verhält es sich da anders.

Aber es handelt sich ja auch um zwei debounce Befehle, also etwa so:

debounce pind.0, 1 , label

label:
Do
debounce pind.0, 1 , label2
Loop

label2:

label:
Do
lcd "test"
Loop until exit = 1

Ich würde vermuten, dass der zweite debounce schon anspricht obwohl ich die Taste zwischenzeitlich nicht losgelassen habe. Aber wie gesagt, dass müsste ich real mal antesten, in der Simulation ist es auf jeden Fall so.


@Feratu

Danke...so könnte ich es mal probieren. Allerdings brauch ich das an vielen verschiedenen Stellen - und dann wird das ziemlich unübersichtlich und lang...

python_rocks
25.03.2008, 23:08
Aber es handelt sich ja auch um zwei debounce Befehle
Hallo elcapitano!

Zwei DEBOUNCE-Befehle. Dann funktioniert das natürlich nicht. Wenn dann nur ein DEBOUNCE-Befehl je Taster. Und die Menüebene merkst du dir in einer Variable.


$regfile = "M8def.dat"
$crystal = 8000000
$hwstack = 32
$swstack = 10
$framesize = 40
$baud = 38400


'TASTER1 an PD2 (zieht nach VCC; Pollin Eval-Board)
Taster1 Alias Pind.2
Config Pind.2 = Input

'TASTER2 an PD3 (zieht nach VCC; Pollin Eval-Board)
Taster2 Alias Pind.3
Config Pind.3 = Input

Dim Old_menu_level As Byte
Dim New_menu_level As Byte


Old_menu_level = 255

Do
Debounce Taster1 , 1 , On_taster1 , Sub
Debounce Taster2 , 1 , On_taster2 , Sub

If New_menu_level <> Old_menu_level Then
Select Case New_menu_level
Case 0
Print "Hauptmenue"
Case 1
Print "Menue 1"
Case 2
Print "Menue 2"
Case 3
Print "Menue 3"
End Select
Old_menu_level = New_menu_level
End If
Loop

End


On_taster1:
Select Case New_menu_level
Case 0 To 2
New_menu_level = New_menu_level + 1
Case 3
'Nichts tun (oder vielleicht einen Ton ausgeben)
End Select
Return


On_taster2:
Select Case New_menu_level
Case 0
'Nichts tun (oder vielleicht einen Ton ausgeben)
Case 1 To 3
New_menu_level = New_menu_level - 1
End Select
Return
mfg
Gerold
:-)

python_rocks
26.03.2008, 00:17
...und noch ein Beispiel mit Menü-Unterpunkten. Ich taufe das Programm hiermit auf den Namen "Hirnverwirbler". 8-[


$regfile = "M8def.dat"
$crystal = 8000000
$hwstack = 32
$swstack = 10
$framesize = 40
$baud = 38400


'TASTER1 an PD2 (zieht nach VCC; Pollin Eval-Board)
Taster1 Alias Pind.2
Config Pind.2 = Input

'TASTER2 an PD3 (zieht nach VCC; Pollin Eval-Board)
Taster2 Alias Pind.3
Config Pind.3 = Input

Dim Old_menu_level As Byte
Dim New_menu_level As Byte
Dim Old_menu_item As Byte
Dim New_menu_item As Byte


Old_menu_level = 255

Do
Debounce Taster1 , 1 , On_taster1 , Sub
Debounce Taster2 , 1 , On_taster2 , Sub

'Menü wechseln
If New_menu_level <> Old_menu_level Then
Select Case New_menu_level
Case 0
Print "Hauptmenue"
Case 1
Print "Menue 1"
Case 2
Print "Menue 2"
Case 3
Print "Menue 3"
End Select
Old_menu_level = New_menu_level
Old_menu_item = 255
End If

'Menüeintrag wechseln
If New_menu_item <> Old_menu_item Then
Select Case New_menu_level
Case 0
'Hauptmenü (zwei Menüeinträge)
Select Case New_menu_item
Case 0
Print "H - 0"
Case 1
Print "H - 1"
End Select
Case 1
'Menue 1 (zwei Menüeinträge)
Select Case New_menu_item
Case 0
Print "M1 - 0"
Case 1
Print "M1 - 1"
End Select
Case 2
'Menue 2 (nur ein Eintrag)
Print "M2 - 0"
Case 3
'Menue 3 (nur ein Eintrag
Print "M3 - 0"
End Select
Old_menu_item = New_menu_item
End If
Loop

End


On_taster1:
Select Case New_menu_level
Case 0 To 1
Select Case New_menu_item
Case 0
New_menu_item = New_menu_item + 1
Case 1
New_menu_level = New_menu_level + 1
New_menu_item = 0
End Select
Case 2
New_menu_level = New_menu_level + 1
New_menu_item = 0
Case 3
'Nichts tun (oder vielleicht einen Ton ausgeben)
End Select
Return


On_taster2:
Select Case New_menu_level
Case 0
Select Case New_menu_item
Case 0
'Nichts tun (oder vielleicht einen Ton ausgeben)
Case 1
New_menu_item = New_menu_item - 1
End Select
Case 1 To 2
Select Case New_menu_item
Case 0
New_menu_level = New_menu_level - 1
New_menu_item = 1
Case 1
New_menu_item = New_menu_item - 1
End Select
Case 3
New_menu_level = New_menu_level - 1
New_menu_item = 0
End Select
Return
mfg
Gerold
:-)

helimike0705
26.03.2008, 19:32
du kannst auch den befehl "bitwait " benutzen ,oder in deiner tasten abfrage einen status setzten.
------------------------------
1. bsp.:
Bitwait Pind.2 , Set

mache irgend etwas

If Pind.2 = 0 Then

------------------------------
2.bsp.:
If Pinc.3 = 0 And Taste3 = 0 Then
Taste3 = 1

mache irgend was

If Pinc.3 = 1 Then
Taste3 = 0
End If

elcapitano
02.04.2008, 22:27
Also...hab das jetzt mit bitwait gelöst...funzt wunderbar:

do
Debounce pind.3 , 0 , label, sub
loop


label:
Bitwait Pind.3 , Reset
....
mache sonstwas
....
Return

Vielen Dank an alle für die super Unterstützung!!!

Grüße
ElCapitano