Forum: Mikrocontroller und Digitale Elektronik Zuweisung Taster


von Petr (Gast)


Lesenswert?

Hallo
Ich möchte mit define einem Taster eine kurzen Namen zuordnen:
1
if (taster1)    
2
// if (!(taster1))
3
  {
4
    // tu was
5
  }
Zuornung des Taster erfolgt damit:
1
#define taster1  PORTA &= ~(1<<PINA1)  // PA1 ein
Das bringt zwar keine Fehlermeldung, funktioniert aber nicht.
Mit Zuordnung von LEDs mach ich es so ohne Probleme. Hab da wohl was 
micht verstanden

von STK500-Besitzer (Gast)


Lesenswert?

1
#define taster1  (PORTA & ~(1<<PINA1))  // PA1 ein

von Wolfgang (Gast)


Lesenswert?

Petr schrieb:
> Zuornung des Taster erfolgt damit:#define taster1  PORTA &= ~(1<<PINA1)
> // PA1 ein
> Das bringt zwar keine Fehlermeldung, funktioniert aber nicht.
> Mit Zuordnung von LEDs mach ich es so ohne Probleme. Hab da wohl was
> micht verstanden

Genau, LEDs hängen an Ausgängen des µC, während Taster an Eingängen 
hängen. Es nützt also nichts, wenn du bei einem Taster irgendetwas auf 
den Port zuweist ("PORTA &="...)

von MaWin (Gast)


Lesenswert?

Petr schrieb:
> Hab da wohl was micht verstanden

Ja.

Tastenzustände muss man einlesen und entprellen,

du machst eine Ausgabe an ein Port.

Auch dein zweiter Ansatz verwendet PORT statt PIN, und entprellt nicht.

Programmieren ist nicht dein Ding.

von Petr (Gast)


Lesenswert?

Habe es jetzt so gemacht:
1
#define taste1 (PINA & (1<<PINA1))  // Taste 1
2
3
if (!(taste1))        // Abfrage Taste 1
4
  {
5
    _delay_ms(20);      // Tasterentprellung
6
    if (!(taste1))      // Abfrage Taste 1
7
      {
8
        tu was ;
9
      }
10
  }

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Petr schrieb:
> _delay_ms(20);      // Tasterentprellung
Das ist Rechenzeitverschwendung.

Du kommst da aber noch selber drauf, falls du in diesen 20ms noch was 
anderes erledigen willst oder sogar musst. Denn wenn dein µC mit 8MHz 
taktet, dann verschenkst du da immerhin 160000 (in Worten 
einhundertsechzigtausend) Maschinenzyklen, in denen der Prozessor was 
Sinnvolles machen könnte...

: Bearbeitet durch Moderator
von Stefan F. (Gast)


Lesenswert?

Lothar M. schrieb:
>> _delay_ms(20);  // Tasterentprellung
> Das ist Rechenzeitverschwendung.

Das ist so eine Sache wie mit der heißen Herdplatte. Manche Erfahrung 
muss der mensch selbst machen, um den Sinn hinter der Warnung zu 
begreifen.

Ist ja auch nicht schlimm, Programme sind nicht in Stein gemeißelt.

von Ich A. (alopecosa)


Lesenswert?

Stefan ⛄ F. schrieb:
> Lothar M. schrieb:
>>> _delay_ms(20);  // Tasterentprellung
>> Das ist Rechenzeitverschwendung.
>
> Das ist so eine Sache wie mit der heißen Herdplatte. Manche Erfahrung
> muss der mensch selbst machen, um den Sinn hinter der Warnung zu
> begreifen.
>
> Ist ja auch nicht schlimm, Programme sind nicht in Stein gemeißelt.

Lothar M. schrieb:
> Petr schrieb:
>> _delay_ms(20);      // Tasterentprellung
> Das ist Rechenzeitverschwendung.
>
> Du kommst da aber noch selber drauf, falls du in diesen 20ms noch was
> anderes erledigen willst oder sogar musst. Denn wenn dein µC mit 8MHz
> taktet, dann verschenkst du da immerhin 160000 (in Worten
> einhundertsechzigtausend) Maschinenzyklen, in denen der Prozessor was
> Sinnvolles machen könnte...

Ist es sinnvoll oder gar guter Stil? Nein!

Funktioniert es für diese eine Sache weil die MCU eh in 90% der Zeit was 
anderes macht? Vermutlich!

Klar gibts bessere Möglichkeiten, sogar hier im Wiki gut dokumentiert. 
Aber why not. Wenn ich q&d was brauche und mich die 20ms nicht stören, 
so what.

Möchte nicht wissen wie viele Anfänger vor diesem Problem stehen, sich 
die hier angebotenen Routinen zur Entprellung anschauen und erstmal 
abschalten weil sie nix verstehen. Gerade durch Arduino und Co gibts so 
viele die sich da ran trauen ohne jemals auch nur eine 
Unterrichtseinheit "programmieren" im Leben gehabt zu haben...

Aber das ist Standard hier, das man nach a) fragt und direkt x) noch mit 
aufgedrückt bekommt, mit sarkastischen Kommentaren (Herdplatte und 
so...) ...

"ja das funktioniert so, ist aber schlecht weil, besser würde es gehen 
wenn du es so machst" ... Stattdessen bekommt man sprichwörtlich das 
Brett vor den Kopf geknallt.

Kratzt euch doch mal an der Nase und fragt euch ob euer eigenes 
Auftreten hier nicht vielleicht einer der Gründe ist warum es hier zu 
geht wie es hier eben zu geht...

von Heiner (Gast)


Lesenswert?

@Ich A:

Vollste Zustimmung!

von Petr (Gast)


Lesenswert?

Das mit den 20ms ist mir vollkommen klar, ist Zeitverschwendung. Das 
Programm soll aber nur das können. Wenn ich mehr Zeit brauche kann ich 
die Entprellung von Peter nehmen.
Brett vor den Kopf geknallt .... ?

von EAF (Gast)


Lesenswert?

Ich A. schrieb:
> Möchte nicht wissen wie viele Anfänger vor diesem Problem stehen, sich
> die hier angebotenen Routinen zur Entprellung anschauen und erstmal
> abschalten weil sie nix verstehen. Gerade durch Arduino und Co gibts so
> viele die sich da ran trauen ohne jemals auch nur eine
> Unterrichtseinheit "programmieren" im Leben gehabt zu haben...

Immerhin sind Blockadefreie Varianten in den Arduino IDE Beispielen 
untergebracht.
Über Effizienz und Schönheit kann man bekanntlich streiten, aber die 
dort vorgestellten Prinzipien funktionieren und werden auch fleißig im 
Arduino Universum eingesetzt.

https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay
https://www.arduino.cc/en/Tutorial/BuiltInExamples/Debounce

von Stefan F. (Gast)


Lesenswert?

EAF schrieb:
> Immerhin sind Blockadefreie Varianten in den Arduino IDE Beispielen
> untergebracht... und werden auch fleißig im Arduino Universum eingesetzt.

Es sind halt nicht alle Arduidioten, wie c-hater-idiot sie gerne nennt.

von Peter D. (peda)


Lesenswert?

Petr schrieb:
> Das mit den 20ms ist mir vollkommen klar, ist Zeitverschwendung. Das
> Programm soll aber nur das können.

Oft kommt später der Wunsch auf, das Programm zu erweitern.
Es ist auch nicht so, daß die 20ms sofort stören. Es können Sachen 
ruckeln, Anzeigen flackern oder Drücke verloren gehen. Dann sucht man 
sich nen Wolf, woran das liegen könnte.
Auch drücken Leute unterschiedlich lange, d.h. man will nur auf die 
Flanke reagieren und keine versehentlichen Doppelaktionen.

von Petr (Gast)


Lesenswert?

Peter D. schrieb:
> Oft kommt später der Wunsch auf, das Programm zu erweitern.

Hast du eine einfache (und kurze) Entprellung? Deine universelle 
Entprellung ist super, aber vielleicht etwas zu gross für das Stück 
Code.

von Falk B. (falk)


Lesenswert?

Petr schrieb:
> Hast du eine einfache (und kurze) Entprellung? Deine universelle
> Entprellung ist super, aber vielleicht etwas zu gross für das Stück
> Code.

Was ist daran zu groß? Die paar Zeilen und die paar Bytes sind 
bedeutungslos.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Petr schrieb:
> Hast du eine einfache (und kurze) Entprellung?
Wie sieht deine Programmstruktur aus?

Hast du eine Schritt-für-Schritt-Struktur, wo z.B. erst auf einen Taster 
(z.B. Start-Taster) gewartet wird, danach dann eine Aktion ausgelöst und 
auf den Abschluss dieser Aktion gewartet wird (z.B. Verfahren eines 
Schrittmotors), und danach der nächste Schritt passiert (z.B. eine 
Meldung angezeigt wird) und wenn der fertig ist, dann geht es wieder von 
vorne los?

Oder hast du eine Hauptschleife, die ständig schnellstmöglich zyklisch 
duchlaufen wird und arbeitest darin mit Zuständen und Automaten?

von Petr (Gast)


Lesenswert?

Petr schrieb:
> Hast du eine einfache (und kurze) Entprellung?

Das ganze Programm sind nur ca. 40 Zeilen und nichts kompliziert. Es 
soll einfach was machen wenn ich einen von 3 Taster drücke. Zeit ist 
dabei vollkommen egal. Ist natürlich möglich das ich noch was anderes 
draus mache, vielleicht mal...
Es ist ein Schritt für Schritt Programm, ganz einfach, nichts grosses. 
Es ging mir nur um den Taster dabei und wie man ihn anders schreiben 
kann.
Die Frage bleibt trotzdem, wer kennt eine ganz einfache Entprellung? Die 
super Entprellung von Peter ist für diese Taster deutlich zu lang.

von Peter D. (peda)


Lesenswert?

Petr schrieb:
> Die
> super Entprellung von Peter ist für diese Taster deutlich zu lang.

Also ist Dein Flash am Anschlag oder wie?

von HildeK (Gast)


Lesenswert?

Petr schrieb:
> Die Frage bleibt trotzdem, wer kennt eine ganz einfache Entprellung?

Wie kann man das in HW machen? Z.B. mit einem n-fach-Schieberegister und 
anschließender NOR- und UND-Verknüpfung. Die NOR spricht an, wenn alle n 
LOW sind, die UND, wenn n HIGH nacheinander eingelesen wurden. Für eine 
HW-Lösung ist das ein ziemlicher Aufwand.

> Die super Entprellung von Peter ist für diese Taster deutlich zu lang.
Naja, von nichts kommt nichts.
Aber wie oben beschrieben, kann man das auch in SW auch machen - mit 
deutlich weniger Aufwand.
Ein Timer (z.B. 2ms) gibt den Takt vor und bei jedem Timerinterrupt 
liest du den Wert des Tasteneingangs und schiebst ihn in eine Variable 
'shift'. Wenn alle n Bits von 'shift' Null bzw. Eins sind, dann änderst 
du eine zweite Variable 'Taste_gedrückt' entsprechend auf Null oder 
Eins. Fertig.
Wenn noch nicht alle Bits gleich sind (während der Prellzeit), dann 
passiert nichts. Und es dauert mindestens n*2ms, bis eine Tastenänderung 
akzeptiert wird; dafür ist das Prellen garantiert abgeklungen.
Ganz einfach zu programmieren ist es, wenn man n=8 nimmt (ein Byte), 
dann muss man die Variable 'shift' nur jedes mal prüfen, ob sie 0x00 
oder 0xFF ist.
Wie auch zu erkennen ist: man muss sowohl beim Drücken als auch beim 
Loslassen der Taste entprellen.

Peter macht es im Prinzip nicht anders, nur sehr geschickt programmiert 
und er kann gleichzeitig vier (oder acht?) Tastenpins einlesen und kann 
noch unterscheiden zwischen lang und kurz gedrückt für eine 
Doppelfunktion.
Auch wenn mein Vorschlag weniger effektiv ist, so macht er dir deutlich, 
welches Prinzip dahinter steckt. Wenn du das verstanden hast, dann 
kopiere einfach den Vorschlag von Peter, denke nicht weitere darüber 
nach und nutze den Code immer wieder.
Für leere Flash-Bereiche in deinem µC gibt's kein Geld zurück ...

von Petr (Gast)


Lesenswert?

Peter D. schrieb:
> Also ist Dein Flash am Anschlag oder wie?

Nein, es ist noch genügend frei. Mir erscheint es für einen kleinen Code 
von vielleicht 20-40 Zeilen um 3 Taster abzufragen und 3 LEDs 
einzuschalten eine Tasterentprellung zu nutzen die im Vergleich viel 
komplizierter ist. Habe auch kürzere Sachen von dir gefunden. Muss mal 
ansehen wie es zusammen passt.

von Petr (Gast)


Lesenswert?

Habe mir den Code von Petr gesucht. Meine diesen 
https://www.mikrocontroller.net/articles/Entprellung
Das mit "Debounce-Makro von Peter Dannegger" gefällt mir sehr gut. 
versuche mal rauszubekommen wie ich es nutzen kann. Eines ist mir aber 
schon aufgefallen was ich nicht verstehe:
1
#define debounce( port, pin )                                         \
2
({                                                                    \
3
  static uint8_t flag = 0;     /* new variable on every macro usage */  \
4
  uint8_t i = 0;                                                      \
5
                                                                      \
6
  if( flag ){                  /* check for key release: */           \
7
    for(;;){                   /* loop ... */                         \
8
      if( !(port & 1<<pin) ){  /* ... until key pressed or ... */     \
9
        i = 0;                 /* 0 = bounce */                       \
10
        break;                                                        \
11
      }                                                               \
12
      _delay_us( 98 );         /* * 256 = 25ms */                     \
13
      if( --i == 0 ){          /* ... until key >25ms released */     \
14
        flag = 0;              /* clear press flag */                 \
15
        i = 0;                 /* 0 = key release debounced */        \
16
        break;                                                        \
17
      }                                                               \
18
    }                                                                 \
19
  }else{                       /* else check for key press: */        \
20
    for(;;){                   /* loop ... */                         \
21
      if( (port & 1<<pin) ){   /* ... until key released or ... */    \
22
        i = 0;                 /* 0 = bounce */                       \
23
        break;                                                        \
24
      }                                                               \
25
      _delay_us( 98 );         /* * 256 = 25ms */                     \
26
      if( --i == 0 ){          /* ... until key >25ms pressed */      \
27
        flag = 1;              /* set press flag */                   \
28
        i = 1;                 /* 1 = key press debounced */          \
29
        break;                                                        \
30
      }                                                               \
31
    }                                                                 \
32
  }                                                                   \
33
  i;                           /* return value of Macro */            \
34
})
Welche Funktion haben ({ und }) am Anfang und Ende?
Haben die Zeichen \\\\ am Ende auch was mit dem Code zu tun oder dienen 
sie einfach zur Abgrenzung?
Dann steht da noch #define debounce( port, pin ) gefolgt von diesen 
Klammern ({ ... }). ????
Sorry da sehe ich nicht durch. Bitte um Aufklärung.

von Manfred (Gast)


Lesenswert?

Lothar M. schrieb:
> Petr schrieb:
>> _delay_ms(20);      // Tasterentprellung
> Das ist Rechenzeitverschwendung.
>
> Du kommst da aber noch selber drauf, falls du in diesen 20ms noch was
> anderes erledigen willst oder sogar musst.

Das ist ein an den Haaren herbei gezogenes Problem, was man nur in 
wenigen Anwendungen hat.

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.