Tasten von verschiedenen Ports auslesen

Gast #178096
Lesenswert?

Hallo an Alle,

ich habe fünf Taster(aktiv-Low) deren Zustand ich gern einlesen
würde.Ist ein Taster gedrückt, soll eine Aktion ausgeführt werden.Aber
nicht solange der Taster gedrückt ist, sondern pro Tastendruck eine
Aktion(Entprellen). Als Sicherheit will ich verhindern, dass zwei
Tasten gleichzeitig gedrückt werden können.
Wie kann ich das ganze umsetzen, wenn ich nun 3 Taster an PORTD 5-7
habe und zwei an PORT 6-7?

Vielen Dank,...

Tschüß Thomas
Gast #178098
Lesenswert?

ich habe das ganze jetzt erstmal so gelöst:

if (bit is clear(PIND, PIND5) {
   ...
if (bit is clear(PIND, PIND6) {
   ...
if (bit is clear(PIND, PIND7) {
   ...
if (bit is clear(PIND, PINE6) {
   ...
if (bit is clear(PIND, PINE7) {
   ...
in der Schleife habe ich jeweils einen Counter hochgezählt zum
Entprellen.

Aber irgendwie ist das ganz schön viel Code für so ein bissl
Entprellen. Geht das nicht irgendwie einfacher?

Danke an Alle,

Thomas
Gast #178100
Lesenswert?

Hi Peter,

Deine Routine habe ich mir schon angeschaut. Dabei konnte ich nicht
genau feststellen, ob das ganze über den Timer gesteuert wird oder
alles ohne Timer funktioniert. Kannst Du mir diesbezüglich vielleicht
eine kleine Erklärung geben?

Vielen Dank,

Ahoi Thomas
Gast #178102
Lesenswert?

Hi Peter,

habe mir jetzt nochmal Deine Entprell-Routine angeschaut und es
versucht in meinem Programm zu realisieren. Leider entprellt es bei mir
nicht :-(! Was könnte ich also noch falsch gemacht haben?
Habe den Counter0 initialisiert und mit blinkender LED überprüft...das
geht also.
Dann habe ich Deinen Code reingehackt...dabei habe ich i= (PIND 0xE0)
|(PINE 0xC0); so gesetzt. Soll also für PIND5-7 und PINE6,7 sein.
Danach so weiter wie Du geschrieben hast.

In meiner for();; Schleife habe ich die Interrupts aktiviert(sei;) und
ne Abfrage nach meiner Taste gemacht:

if(bit_is_clear(PIND, PIND5)) {
   if(key_press)....also nur wenn Taste entprellt ist
    {...
    }}

Leider wird so nichts entprellt. Kannste mir vielleicht noch einen
Hinweis geben, was ich da noch nicht richtig verstanden habe?

Danke Thomas
Gast #178106
Lesenswert?

Hallo,

bit_is_clear (, );

Die Funktion bit_is_clear prüft, ob ein Bit gelöscht ist. Wenn das Bit
gelöscht ist, also auf 0 ist, wird ein Wert ungleich 0 zurückgegeben.

Diese Erklärung ist in der AVR-GCC-Einführung in der Wiki zu finden. Du
kannst auch die ganz normalen ANSI-C-Befehle verwenden
(Variable & (1<<Bitnummer)).


Gruß Elektrikser
Gast #178108
Lesenswert?

Halli hallo,

also ich habe das jetzt nochmal ausprobiert und leider habe ich das
Problem immer noch nicht lösen können. Also ich habe zur Zeit nur noch
eine Abfrage und zwar:
if(key_press) {
    ...
    key_press=0;
}
Das hat zur Folge das sofort beim Einschalten OHNE Tastendruck...die
Aktion ausgeführt wird! Und wenn ich die Taste drücke, tut sich leider
gar nichts!

Wo kann denn da jetzt noch der Fehler liegen? Ich bin mir nicht sicher
wie die Klammern zwischen den ganzen Bitoperationen gesetzt werden
müssen. Zum Beispiel in der Zeile:
ct1=ct0^ct1&i
Was hat denn da den Vorrang?

Ist die Vorinitialisierung der Variablen von Bedeutung?

Noch eine Frage, wenn ich nur noch Key_press Abfrage, dann ist es mir
ja nicht mehr möglich zu unterscheiden, welche Taste jetzt gedrückt
worden ist oder täusche ich mich da? Wenn nich, wie kann ich denn die
Tasten unterscheiden?


Wäre nett, wenn Ihr mir nochmal helfen könnt...
Gast #178110
Lesenswert?

Hi Peter,

heute Morgen habe ich mir in aller Ruhe nochmal das Schedule-Programm
angeschaut. Obwohl ich durch die vielen Funktionen nicht 100 prozentig
durchgesehen habe, konnte ich bei meinem Programm einen kleinen Erfolg
verzeichnen. Es entprellt jetzt und es erkennt die richtigen Tasten.
Nur konnte ich die Tasten noch nicht kombinieren. Dazu habe ich mal
noch ein paar leichte Fragen. Ich check das einfach mit dem
Schieboperator nicht. Ich versteh zwar Links-oder Rechtsschieben, aber
nicht in Verbindung mit folgenden Kommandos:

i=(PIND>>2)

Was wird denn dabei geschoben??? Was steht denn jetzt in i???

Deswegen versteh ich auch folgende Zeile Deines Schedule Codes nicht:

if(get_key_press(1<<PB6))...z.Bsp.

erstmal was soll (1<<PB6) bedeuten? Und zweitens PB6 ist ja ein Bit des
Datenausgangsregister und ich will doch ne Taste einlesen??? Was hat das
damit auf sich?

Falls Du mir das mal erklären kannst, kann ich bestimmt auch verstehen,
wie ich endlich die Tasten PIND5-7 und PIN6-7 auf i legen kann:

i=(PIND & 0xE0)|(PINE & 0xC0)...geht leider nicht.

werden da Bit 6 und 7 überschrieben?

Würde mich über eine Antwort sehr freuen.

Vielen Dank schon mal im Vorraus,

Ciao Thomas
Gast #178111
Lesenswert?

Hi!

Schieben (shiften) kann man mit multiplizieren (linksschieben) oder mit
dividieren (rechtsschieben) ersetzen!

i=(PIND>>2)

Hier wird der Inhalt von PIND um zwei Stellen nach rechts verschoben,
d. h., der Inhalt von PIND wird durch 4 (2**2) geteilt. Danach wird das
Ergebnis i zugewiesen.

if(get_key_press(1<<PB6))

Hier wird get_key_press(..) das Bit PB6 als Parameter übergeben.
(1 << PB6) bedeutet, daß 1 um PB6 stellen nach links geschoben wird. In
diesem Falle um 6 Stellen. Das wiederum entspricht einer Multiplikation
mit 64 (2**6).

Wenn Du verschiedene Pins von verschiedenen Ports in einer Variablen
speichern willst, dann musst Du darauf achten, daß die bits Sortiert
werden müssen und sich nicht gegenseitig überschreiben.
Gast #178112
Lesenswert?

Hey OldBug,

vielen Dank für die Erklärung...ich hoffe das habe ich soweit
verstanden.

Das mit den verschieden Pins haut bei meinem Programm leider nicht hin.
Wieso weiß ich auch nicht? Ich habe mir das jetzt so gedacht:

i=(PIND>>5)|(PINE & 0xC0);

Dann müßten die Bits 0-5 von PIND nach rechts weggeschoben werden und
der Rest mit PINE verodert werden. So das dann in i
=PINE7,PINE6,0,0,0,PIND7,PIND6,PIND5...stehen müßte oder?

CU Thomas
Gast #178113
Lesenswert?

Hey OldBug und Peter,

ich habs endlich hinbekommen!!!! Mich hat der Parameter bei
get_key_press verwirrt. Ich dachte es muß PBx sein...sozusagen was in
dem Bit steht. Aber nach der Erklärung von OldBug müßte ja zum Beispiel
(1<<PB6) gleich (1<<6) sein. Sozusagen einfach um 6 Bit geschiftet. Auf
jeden Fall habe es jetzt folgendermaßen gelößt:

i=(PIND & 0xE0)|(PINE>>3); //PIND7,PIND6,PIND5,PINE7,PINE6,...
i ^= ~key_state;
...

if(get_key_press(1<<7)) Schalter PIND7
if(get_key_press(1<<6)) Schalter PIND6
if(get_key_press(1<<5)) Schalter PIND5
if(get_key_press(1<<4)) Schalter PINE7
if(get_key_press(1<<3)) Schalter PINE6

Die ersten Tests liefen erfolgreich. Vielleicht kann mir jetzt jemand
das ganze auch noch erklären ;-)))...

Ciao Thomas

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren