mikrocontroller.net

Forum: Compiler & IDEs Tasten von verschiedenen Ports auslesen


Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Thomas2. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mach das abfragen einfach mit ner fallenden Flanke.
Bsp:
if (bit_is_set(PIND, PIND5)
   {
    loop_until_bit_is_clear(PIND, 5);
    ...

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man könnte die Bits zusammen fassen und dann meine Entprellroutine
(Codesammlung) nehmen:

i = (PIND >> 2) | (PINE & 0xC0); // Bit 3,4,5,6,7
i ^= ~key_state;                 // key changed ?
usw.


Peter

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Timer macht den Entprelltakt, kann aber noch für andere Sachen
benutzt werden. Das ist besser als die Zeit nutzlos zu verwarten.


Lies Dir mal den ganzen Thread in Ruhe durch, das dürfte alles
erklären.


Peter

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey Peter,...wo bist Du?

Hab gerade noch ein wenig probiert und bei mir ist Key_press immer 1,
wenn keine Taste gedrückt ist! Was mache ich falsch?

Danke Thomas

Autor: Peter Dannegger (peda)
Datum:

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

Ne, doppelt gemoppelt geht nicht.

Die Routine macht alles für Dich, d.h. vergiß die Pins, lies nur
key_press aus (und setz es zurück).


Peter

Autor: Simi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
was ist bit_is_clear ??
n makro oder was ?

Autor: Elektrikser (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Elektrikser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das war wieder ein mieser Satzbau, aber egal.

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Peter Dannegger (peda)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier ist ein Beispiel, welches Du leicht auf dem STK500 ausprobieren
kannst:

http://www.mikrocontroller.net/forum/read-4-49709.html#new

Daraus geht auch hervor, wie Du die Tasten einzeln abfragst:

Danach kannst Du dann die Erweiterung auf verschiedene Ports
probieren.

Anbei die Rangfolge in C.


Peter

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.