Forum: Compiler & IDEs Flankenerkennung für fallende Flanke als Funktion?


von Mathias O. (m-obi)


Lesenswert?

Hallo,

ich hab mir mal eine Flankenerkennung für eine fallende Flanke gebaut:
1
uint8_t Temp = 0;
2
    
3
if (Taster_1)
4
{
5
  Temp = Taster_1;
6
  _delay_ms(20);
7
  if (Temp && !Taster_1)
8
  {
9
    PORTC ^= 0xff;
10
  }
11
      
12
}

Nun möchte ich sie gerne als Funktion haben, so dass es für mehrere 
Tasten verfügbar ist. Und ich dann so nutzen kann:
1
if (key-up((Taster_1)) PORTC ^= 0xff;
2
3
if (key-up((Taster_2)) PORTB ^= 0xff;

Achja Taster_1 und Taster_2 sind natürlich schon vorher deklariert 
worden.

Wie muss das dann aussehen als Funktion? Die Funktion heißt dann key_up.

von Peter D. (peda)


Lesenswert?


von Karl H. (kbuchegg)


Lesenswert?

Ich versteh ehrlich nicht, warum du dich gegen eine 100% sichere 
Tastenentprellung und Erkennung so dermassen wehrst.

von Mathias O. (m-obi)


Lesenswert?

Warum wehren, ich hab es doch schon akzeptiert. Das soll doch nur ne 
fallende Flanke erkennen.

von Karl H. (kbuchegg)


Lesenswert?

Das von dir im OB gepostete wird so gut wie niemals eine fallende Flanke 
erkennen.
Eine Flanke ist etwas das dynamisch auftritt, du weist nie wann. Also 
muss es zumindest irgendeine Form von Schleife geben, die regelmässig am 
Port-Pin nachsieht, ob sich was verändert hat. Um eine Veränderung zu 
erkennen musst du aber den Zustand kennen, der vorhanden war, ehe du 
erneut nachsiehst ob sich etwas verändert. Dazu muss dieser 
'vorhergehende Zustand' irgendwo zwischengespeichert werden.

Daher muss eine Funktion, die erkennen kann ob sich der Zustand der Pins 
im Vergleich zum nächsten mal nachsehen verändert hat, zumindest 2 
Parameter haben: wo soll nachgesehen werden und was war der zuletzt 
festgestellte Zustand. Jetzt wirst du aber erkennen, dass dieses 'wo 
soll nachgesehen werden' gar nicht so simpel zu realisieren ist.

Am ehesten könnte man sich noch auf sowas einigen:

uint8_t isFlanke( uint8_t newValue, uint8_t mask, uint8_t* oldValue )
{
  uint8_t retVal = FALSE;

  if( ( newValue & mask ) != ( oldValue & mask ) )
    retVal = TRUE;

  oldValue &= ~mask;
  oldValue |= ( newValue & mask );

  return retVal;
}

#define KEY_1  ( 1 << PD0 )
#define KEY_2  ( 1 << PD1 )
#define KEY_3  ( 1 << PB5 )

int main()
{
  uint8_t prevPinD, prevPinB;

  ...

  prevPinD = PIND;
  prevPinB = PINB;

  while( 1 ) {

    if( isFlanke( PIND, KEY_1, &prevPinD ) )
      ...

    if( isFlanke( PIND, KEY_2, &prevPinD ) )
      ...

    if( isFlanke( PINB, KEY_3, &prevPinB ) )


Aber selbst das ist ziemlicher Mist. Horrend ineffizient. Da ist es sehr 
viel simpler die Flankenerkennung beim Aufrufer zu machen und auf eine 
Funktion zu verzichten.

von Mathias O. (m-obi)


Lesenswert?

Den Code den ich gepostet habe, war nur ein Auszug aus dem ganzen 
Programm. Ich habe das in einer Endloschleife drin. Aber das meine 
Flankenerkennung funktioniert ist fakt.

Dann mach ich es einfach so, wenn ich die Erkennung benötige, schreib 
ich einfach für den taster die paar Zeilen dahin, nicht als Funktion, 
sonder ganz normal, so wie ich es oben gepostet habe.

von Micha (Gast)


Lesenswert?

Ich denke das müsste sich mit dem gleichen Code wie die Entprellung 
gestern realiseren lassen, sprich dem hier 
Beitrag "Universelle Tastenabfrage". Und die Entprellung 
ist dann auch gleich inklusive.

von Karl H. (kbuchegg)


Lesenswert?

Mathias Obetzhauser wrote:
> Den Code den ich gepostet habe, war nur ein Auszug aus dem ganzen
> Programm. Ich habe das in einer Endloschleife drin. Aber das meine
> Flankenerkennung funktioniert ist fakt.

Deine Funktionalität da oben eignet sich maximal zur Abfrage von 
mechanischen Tastern und das auch nur wenn du nicht zuviele Tasten hast 
oder einen gutmütigen Benutzer.

Jedesmal wenn der Eingangspin eine 1 auweist, wartet die Funktion 20ms, 
ob sich der Pegel verändert. Für was anderes als mechanische Taster 
(also alles was nicht prellt oder prellen kann) ist sowas nicht zu 
gebrauchen.
Und im Falle von tatsächlich notweniger Entprellung hast du mit der PeDa 
Methode eine erstklassige Möglichkeit für nicht zu schnell wechselnde 
Eingangssignale (Ein Benutzer handelt aus Sicht eines µC in 
Superzeitlupe)

Merke: Alle Methoden, die darauf beruhen, dass auf irgendetwas mit einem 
delay gewartet werden muss, sind meistens fragwürdig. Manchmal kann man 
das machen, wenn man sonst keine kritischen Timings einhalten muss. Aber 
meist ist eine Lösung die ohne delay auskommt die bessere Wahl.

von Peter D. (peda)


Lesenswert?

Mathias Obetzhauser wrote:
> Warum wehren, ich hab es doch schon akzeptiert. Das soll doch nur ne
> fallende Flanke erkennen.

Das ist bereits im Beispiel drin:
1
key_press |= key_state & i;    // 0->1: key press detect
Benötigt also nur eine einzige Zeile für 8 Tasten.
Also pro Taste eine achtel Zeile, kürzer gehts nimmer.


Peter

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.