Forum: Mikrocontroller und Digitale Elektronik Frage: RS-FlipFlop in C


von Hölscher (Gast)


Lesenswert?

Hallo Forum Freunde
ich Möchte gerne ein einfaches RS-Flip-Flop realisieren.
Kann mir jemand weiter helfen. (ANSI-C)

Mit freundlichen Grüßen
Christian Hölscher

Mein Eigener Quellcode für einen Taster:

unsigned char Taster_1(void)
{
   unsigned char i;

   if (P3_0==1)
   {
      wait(100);
    if (P3_0==1)
    return 0;
   }

   for (i=0; i<10; i++)
   {
    wait(500);
    if (P3_0==0) i=0;
   }

    return 1;
}

von Rolf F. (Gast)


Lesenswert?

Dafür nimmt man besser eine Timer-ISR die z. B. jede ms aufgerufen
wird:

...
if (P1_IN & BUTTON_1)
  if (counter_1 < LIMIT)
     counter_1++;
else
  counter_1 = 0;
if (LIMIT_1 == counter_1) // button pressed LIMIT_1 ms without pause
 do_someting_1();
...

beispielsweise mit #define LIMIT 100.
counter_1 muss eine globale Variable sein, die außerhalb der ISR nur
abgefragt wird, außer man kann eine Funktion wie atomic_write
implementieren, die thread-save schreiben kann.

von Rahul (Gast)


Lesenswert?

jetzt würde mich schon interessieren, wieso das ein RS-FlipFlop sein
soll. Da wird doch überhaupt nichts gespeichtert.
Für mich sieht das eher wie ein entprelltes Nicht-Glied aus.
Naja, eigentlich liefert die Funktiongrundsätzlich eine 1 zurück, würde
ich jetzt mal so vermuten.
Ein RS-FlipFlop hat doch im Normalfall zwei Eingänge: Ein Setz- und ein
Rücksetzeingang.
Wenn man ein FlipFlop irgendwie triggert und es nach einiger Zeit in
seinen Ursprungsszustand ohne weiteres Zutun zurückfällt, nennt man es
wohl eher Monoflop.
So, genug kluggeschissen!

wie wäre es so: (C-Mischmasch)

volatile unsigned char output;
if (P3_0 == 1) // Taster gedrückt
{
   wait(100); // 100ms warten
   if (P3_0 == 1) // Taster immer noch gedrückt
   {
     output = ~output;  // Invertierung des Ausgangs
     while (P3_0 ==1);  // warten bis die Taste wieder
                        // losgelassen wurde
   }
}

Notfalls müsste man output entweder global definieren oder der Funktion
übergeben und dann am Ende per "return output" zurückliefern. Oder
sogar als Pointer...

Gruß Rahul
   }

von Rolf F. (Gast)


Lesenswert?

Das wäre das Dümmste was man machen kann, denn schon durch zwei
Störpulse im Abstand von 100 ms würde das wait(100) nix bringen;
deshalb verwende ich einen Zähler.
Das wait(100) würde zudem alles andere, außer höherpriore Interrupts,
blockieren.

Und als output nimmt man normalerweise sowas für einen Port:

#define rGPFODAT (*(volatile unsigned int*)(0815)) //Port F output data

von Hölscher (Gast)


Lesenswert?

Hallo Rolf F. und Rahul
vielen Dank für die schnelle Antwort.

Ihr habt mir beide sehr gut weiter geholfen

Mit freundlichen Grüßen
Christian

von Rahul (Gast)


Lesenswert?

@Rolf:
Nagut, ich bin jetzt von Christians Anfrage zur Realisierung eines
RS-FlipFlops ausgegangen. Dass meine Lösung perfekt ist, habe ich nie
behauptet. Natürlich gibt es andere Methoden, Taster zu entprellen.
So wie ich Christian verstanden habe, ging es um das Prinzip.
Die Formulierung mit dem #define ist mir bisher zwar noch nicht
untergekommen, kann aber sein, dass man das bei der Programmierung von
AVR nicht braucht (bin mit den Ports auch so zu recht gekommen...)
Naja, ich bin auch nur Mechatronik-Student, kein Informatiker...
Schönen Abend noch
Rahul

von Rolf F. (Gast)


Lesenswert?

Ok, ich bin nur gegen solche zu simplen Sachen, weil ich sowas nämlich
reparieren muß und schon mit IDEs (von IAR) zu kämpfen habe, bei denen
man z. B. den Präprozessor allein nicht aufrufen kann, der Compiler
fast alle möglichen undefinierten Ausdrücke klaglos akzeptiert u.
mehrere Abweichungen vom C-Standard hat; deshalb konnte ich die meisten
Stellen, an denen busy waiting einiges Wichtige an einigen Stellen
beliebig lange blockieren kann, noch nicht beseitigen.

von Peter D. (peda)


Lesenswert?

Da hat Rahul vollkommen recht.

Der obige Code hat mit einem RS-FF auch nicht das geringste zu tun.

Ein RS-FF hat, wie ja der Name schon sagt, zwei Eingänge, einen Reset
und einen Set Eingang.
Und eine kurze 1 am Set bewirkt eine 1 am Ausgang, eine kurze 1 am
Reset bewirkt eine 0 am Ausgang. Beide = 0 hält den alten Zustand,
beide = 1 ist undefiniert.


Der obige Kode sieht eher nach dem mißglückten Versuch einer
Tastenentprellung (Debounce) aus, aber sowas hatten wir im Form ja
schon zur Genüge.
Da brauchts also keine weiteren Kommentare, einfach nur die
Suchfunktion benutzen.


Peter

von Hölscher (Gast)


Lesenswert?

Hallo Peter wie so ist der Versuch meiner Tastenentprellung mißglückt?
Ich finde wenn man so etwas behauptet sollte man auch eine bessere
Lösung präsentieren.

Nörgeln kann ja jeder..

Mit freundlichen Grüßen
Christian

von Alexander (Gast)


Lesenswert?

Hat er doch, du musst nur in die Codesammlung schauen. Von daher hat er
im Gegensatz zu dir auch das Recht, eine große Lippe zu riskieren!

Alex

von Peter D. (peda)


Lesenswert?

"Ich finde wenn man so etwas behauptet sollte man auch eine bessere
Lösung präsentieren."

Wenn Du sie nicht gefunden hast, dann hast Du auch nicht danach
gesucht.
Soll ich das etwa für Dich machen ?


In dem äußerst unwarscheinlichen Fall, daß die Funktion doch das macht,
was Du willst (CPU totlegen, solange P3_0==0), hättest Du es auch so
beschreiben müssen. Einen RS-FF macht sie jedenfalls nicht.


Peter

von Hölscher (Gast)


Lesenswert?

Hallo Peter
vielen Dank für deine Antwort.

Mit freundlichen Grüßen
Christian

P.S. Alexander ich wollte deinem Peter nichts, bleib locker

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.