Hallo,
ich möchte gerne eine gemeinsame Tastenabfrage in der folgenden Schleife
einbauen....
if (!(PORTD.IN & 0b00000001) && (...) && (...))
{
Tu was....
}
...bis jetzt wird nur der Tastenzustand am PIN0 abgefragt mit PORTD.IN &
0b00000001
Was muss ich ändern wenn ich irgendeine Taste am Port abfragen möchte?
Es sind 8 Tasten an einem Port angeschlossen und sowie eine aber auch
nur eine gedrückt wird soll ein Befehl ausgeführt werden.
Sämtliche Versuche mit dem Befehl PORT.IN scheiterten bisher.
Gruß Daniel
Daniel schrieb:> if (!(PORTD.IN & 0b00000001) && (...) && (...))
...
> Was muss ich ändern wenn ich irgendeine Taste am Port abfragen möchte?
Wenn do "oder" meinst, mußt du auch "||" schreiben.
Erste Frage wäre, wie deine Tasten angeschlossen sind, d.g. ob sie beim
Drücken L oder H liefern. Dann kannst du mit "&" eine Maske auf die
erforderlichen Tasten legen und prüfst ober das Ergebnis bzw. das
Inverse == 0 ist.
Werner schrieb:> enn do "oder" meinst, mußt du auch "||" schreiben.>> Erste Frage wäre, wie deine Tasten angeschlossen sind, d.g. ob sie beim> Drücken L oder H liefern. Dann kannst du mit "&" eine Maske auf die> erforderlichen Tasten legen und prüfst ober das Ergebnis bzw. das> Inverse == 0 ist.
Also der Port D wurde als Eingang festgelegt
Mit der Maskenfunktion
PORTCFG.MPCMASK |=(1<<PIN0_bp) | (1<<PIN1_bp) | (1<<PIN2_bp) |
(1<<PIN3_bp)
| (1<<PIN4_bp) | (1<<PIN5_bp) | (1<<PIN6_bp) |
(1<<PIN7_bp);
wurden die PINS am Port D maskiert
anschließend wurden mit der Gruppenfunktion
PORTD.PIN0CTRL = PORT_OPC_PULLUP_gc;
die Pullups aktiviert.
Mit anderen Worten wenn eine Taste gedrückt wird, liegt am Porteingang
eine 0 an. Daher die verneinte Abfrage !(PORTD.IN & 0b00000001)
if (!(PORTD.IN & 0b00000001) && (Bedingung1==TRUE) &&
(Bedingung2==TRUE))
{
Tu was....
}
Die Verknüpfung && hat bisher noch nichts mit den anderen Tasten zu tun
und
soll nur prüfen ob die Bedingung1 und Bedingung2 aus dem übrigen Code
auch TRUE ist.
Wie genau muss jetzt die Codezeile aussehen wenn ich alle 8 Tasten auf
Low-Zustand abfragen will?
Folgendes funktioniert leider nicht :
if (!(PORTD.IN & ((0b00000001)||(0b00000010))) && (Bedingung1==TRUE) &&
(Bedingung2==TRUE))
{
Tu was....
}
Verstehe ich Dich richtig? Am Port liegt 0b11111111 an, wenn keine Taste
gedrückt wird und etwas anderes, wenn eine gedrückt wird?
Wenn das stimmt, dann gibt diese Umformulierung ja schon die Antwort.
Einfach auf PORTD.IN != 0b11111111 testen, um zu sehen ob irgendeine
Taste gedrückt ist.
> und sowie eine aber auch nur eine gedrückt wird
Ach, Du willst die Aktion nicht machen, wenn zwei Tasten gleichzeitig
gedrückt werden?
Na dann musst Du die Maskierungen wie in (PORTD.IN & 0b00000001)
weglassen, weil eine Maskierung gerade macht, dass die anderen Bits egal
sind. Teste also einfach auf alle 8 Zustände, die Du haben willst
(PORT.IN == 0b11111110) || (PORT.IN == 0b11111101) || ...
M. H. schrieb:>> Ups, habe im case default das break vergessen...>> Wieso? Es schadet zwar nicht, das dort zu haben, aber notwendig ist es> nicht.
Ich habs halt gerne strukturiert :-). Aber klar, ist überflüssig.
Compiler würde es eh wegrationalisieren.
M. H. schrieb:> Ach, Du willst die Aktion nicht machen, wenn zwei Tasten gleichzeitig> gedrückt werden?>> Na dann musst Du die Maskierungen wie in (PORTD.IN & 0b00000001)> weglassen, weil eine Maskierung gerade macht, dass die anderen Bits egal> sind. Teste also einfach auf alle 8 Zustände, die Du haben willst> (PORT.IN == 0b11111110) || (PORT.IN == 0b11111101) || ...
Also die Aktion soll gemacht werden wenn irgendeine Taste von den 8
Tasten gedrückt wird. Vorzugsweise soll nichts passieren wenn mehrere
Tasten gleichzeitig gedrückt werden.
Muss ich jedesmal PORTd.IN schreiben oder kann ich das noch verkürzen?
Dann liegt mein Fehler also bei der and & Operation richtig?
Sprich aus dem & muss ein == werden...
Daniel schrieb:> Muss ich jedesmal PORTd.IN schreiben oder kann ich das noch verkürzen?
Schreib ich eigentlich chinesisch? In meinem Codefragment wird genau
einmal PORTD.IN abgefragt.
Wenns dir nur darum geht, irgendeine einzelne taste abzufragen:
1
voidbutton_interpreter(void){
2
switch(PORTD.IN){
3
case0xFE:// Taste an Bit0 gedrückt
4
case0xFD:// Taste auf Bit1
5
case0xFB:
6
case0xF7:
7
case0xEF:
8
case0xDF:
9
case0xBF:
10
case0x7F:// hier tu ich was
11
break;
12
// usw.
13
casedefault:// alle nicht behandelten Tastendruckkombinationen
Matthias Sch. schrieb:> Schreib ich eigentlich chinesisch? In meinem Codefragment wird genau> einmal PORTD.IN abgefragt.
Chinesisch nicht aber du schreibst eine CASE..
und meine Frage war ob man in der if() nur einmal PORTD.IN schreiben
kann und dahinter eine || oder Abfrage machen kann...
Daniel schrieb:> Vorzugsweise soll nichts passieren wenn mehrere> Tasten gleichzeitig gedrückt werden.
Darum brauchst Du Dir keine Sorgen zu machen. Kein Mensch kann 2 Tasten
innerhalb weniger ns zusammen drücken.
Es wird immer eine Taste zuerst gedrückt werden.
Peter
Daniel schrieb:> meine Frage war ob man in der if() nur einmal PORTD.IN schreiben> kann und dahinter eine || oder Abfrage machen kann...
Nein, das geht nicht. Für den Fall, dass das Auslesen besonders lange
dauert oder es problematisch wäre wenn sich der Port während der
Abarbeitung des if-Statements ändert (beides sehe ich hier nicht), kann
man die Portabfrage natürlich auch in eine Variable schreiben und die
dann testen. Aber auch dann muss man diese mehrmals ins if() schreiben.
Dieses Zwischenspeichern gänge natürlich auch mit einem Funktionsaufruf
if(nur_eine_Taste_gedrückt(PORTD.IN)). Ich bin zwar kein Freund von
case-Anweisungen, aber in diesem speziellen Fall finde ich sie die
bessere Lösung, weil besser lesbar.
M. H. schrieb:> Ich bin zwar kein Freund von> case-Anweisungen
Sag mal warum, würde mich interessieren. Hab hier gerade einen kleinen
Frequenzumrichter (700Watt) mit Mega88, LCD und drei Tasten gebaut, und
die Tastenabfrage mit switch und case ist prima, da ich eben auch zwei
gleichzeitig gedrückte Tasten auswerten und für Sonderfunktionen
benutzen kann.
Bei den verschachtelten if's und else's verliert man m.E. viel schneller
den Überblick und verbaut sich die Erweiterbarkeit.
Ich könnte mir nämlich vorstellen, das der TO irgenwann doch mal
zwischen den Buttons unterscheiden will und dann die if's wieder
auseinanderdröseln muss.
Bei meinem Konstrukt hingegen schreibste im case dann deine gewünschte
Funktion und fertig.
Matthias Sch. schrieb:> die Tastenabfrage mit switch und case ist prima
Ist sie nicht.
Man muß erst alle anderen Tasten ausmaskieren.
Und es kommen ja noch weitere Probleme hinzu, wie Entprellung und
Flankenerkennung.
Man schreibt sich daher am besten eine Funktion dafür:
Matthias Sch. schrieb:> Sag mal warum, würde mich interessieren.
Wie gesagt: In diesem Fall finde ich Case sehr elegant und würde es auch
so nutzen. Aber so grundsätzlich nutze ich Case nicht gern. Eher aus dem
Bauch heraus als mit harten Fakten belegbar. Liegt wohl eher daran, dass
ich nicht nur in C programmiere, sondern auch in anderen Sprachen (in
denen es ein Case nicht gibt). Außerdem ist Case nicht (nachträglich) um
zusätzliche Bedingungen (auf andere Variablen) erweiterbar und nicht so
mächtig wie ifs. (Du schreibst oben etwas von verschachtelten if-else.
Solche Dinge sind inhaltlich doch überhaupt nicht mit Cases abzubilden?)
Zu guter letzt: Die Case-Anwendung ist syntaktisch ein Fremdkörper in C.
Überall gibt es Code-Blöcke, die mit geschweiften Klammern
zusammengehalten werden. Nur an einer Stelle muss man die gleiche Sache
anders notieren: bei Cases.
Peter Dannegger schrieb:> Matthias Sch. schrieb:>> die Tastenabfrage mit switch und case ist prima>> Ist sie nicht.> Man muß erst alle anderen Tasten ausmaskieren.
Sorry, aber auch Leute, die exzellente Algorithmen für die
Tastenerkennung geschrieben haben, sollten einen Thread lesen und die
Anforderungen verstehen bevor sie antworten.
Mit der Frage nach Flankenerkennung und Entprellung hast Du allerdings
recht. Was sagt Daniel (OP) dazu? Hast Du Dir darüber schon Gedanken
gemacht? Dein jetziger Ansatz wird den entsprechenden Code hunderte oder
tausende Male durchlaufen solange eine Taste auch nur kurz gedrückt
wird. Wäre das okay?