Forum: Compiler & IDEs Frage zu einer IF-Bedingung


von Mathias O. (m-obi)


Lesenswert?

Hallo,

ich habe eine IF-Bedingung und wollte fragen ob das nich kürzer geht.
1
if ( PIND & (1<<2) )

zb als:
1
if ( PIND2 == 1 )

?????


m-obi

von (prx) A. K. (prx)


Lesenswert?

Jag mal die zweite Version durch den Präprozessor vom Compiler (gcc: 
-E), dann wirst du sehen, dass da letztlich
   if ( 2 == 1 )
stehen bleibt.

von Mathias O. (m-obi)


Lesenswert?

Ne geht trotzdem nicht. Er muss ja auch wissen, dass er PIND nehmen 
soll.

von Sven P. (Gast)


Lesenswert?

Geht schon,
1
if (PORTD & _BV(1)) {}
nicht kürzer, aber eleganter...

Ansonsten mit Zeigern und Bitfeldern.

von Mathias O. (m-obi)


Lesenswert?

was heißt denn _BV(1)?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Das ist ein Macro, das den in Klammern übergebenen Wert an einen 
Shiftoperator übergibt ...
1
#define _BV(n) { 1 << n }

von Mathias O. (m-obi)


Lesenswert?

Kann mir einer noch sagen wie das aussieht, wenn ich mit einem Taster 
eine LED an- und ausschalten möchte, also wie Stromstoßrelais?

von Detlev T. (detlevt)


Lesenswert?

In AVR-GCC gibt es auch noch die Makros bit_is_set/bit_is_clear. Das 
sieht dann zum Beispiel so aus:
1
if(bit_is_set(PIND, PIND2)) /* Do anything */;
Am compilierten Code ändert das nichts, ist aber vielleicht besser 
lesbar.

Mathias Obetzhauser wrote:
> Kann mir einer noch sagen wie das aussieht, wenn ich mit einem Taster
> eine LED an- und ausschalten möchte, also wie Stromstoßrelais?

Bei vielen AVRs, aber nicht allen, kann man den Port-Pin toggeln, indem 
man eine "1" an der entsprechenden Position in das Register PINx 
schreibt. Näheres verrät dir das Datenblatt des Prozessors.

von Mathias O. (m-obi)


Lesenswert?

Ich bekomm es einfach mit dem toggeln nicht hin.

Hier nochmal das was ich machen wollte, ganz simpel eigentlich. Taster 
ein > LED ein....Taster ein >LED aus, praktisch wie ein T-Flipflop.

Bitte helft mir.

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


Lesenswert?

> Taster ein > LED ein....Taster ein >LED aus
Deine Denkweise ist falsch. Du willst eigentlich, dass sich der Zustand 
der LED bei jedem erneuten Tastendruck ändern soll. So etwa:
>> Taster wird gedrückt (=steigende Flanke) --> LED = ~LED;

Was du brauchst ist eine Flankenerkennung. Sinnvollerweise auch eine 
Tasterentprellung. Jetzt such mal mit diesen Stichworten hier im Forum 
ein wenig herum, das Problem hatten andere auch schon.

von Mathias O. (m-obi)


Lesenswert?

Ich hab überall geguckt, hab aber nichts brauchbares gefunden. Das kann 
doch nicht so schwer fallen sein, eine Flankenerkennung ein zu baue. In 
anderen Programmiersprachen ist das so einfach, da sind es nur 2-3 
Zeilen. Kann mir jemand mal bitte helfen.

Und wieso kann man eigentlich bei GCC kein "true" und kein "false" 
benützen?
Kann mir jemand sonst noch Eigenheiten von GCC nennen. Anscheinend hab 
ich eine andere C-Sprache gelernt so mit "printf" oder "if Taster == 
true".

von Siddhartha (Gast)


Lesenswert?

Du kannst true und false schon verwenden, du musst einfach die bool.h 
includen (sofern die in deiner Toolchain vorhanden ist). Aber einfache 
#define's lösen dir dieses Problem auch ;)

Also printf gibt es im GCC auch, solange du die stdio.h includest.
Ein if ohne Klammern habe ich jedoch noch nie gesehen...

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Mathias Obetzhauser wrote:

> Ich hab überall geguckt, hab aber nichts brauchbares gefunden. Das kann
> doch nicht so schwer fallen sein, eine Flankenerkennung ein zu baue.

Du hast ein ganz anderes Problem: dein Taster muss erstmal entprellt
werden.  Das macht man normalerweise im Timerinterrupt, den man
periodisch alle ca. 10 ms aufruft.

Lösungen dafür gibt's bereits, wenn ich mich recht entsinne, geistert
hier irgendwo eine von Peter Dannegger herum.

Wenn du die Entprellung hast, dann ist auch die Flankenerkennung
kein Problem, du merkst dir einfach den vorigen Zustand am Anfang
eines jeden Timerinterrupts und vergleichst am Ende, ob sich der
Zustand geändert hat.

> In
> anderen Programmiersprachen ist das so einfach, da sind es nur 2-3
> Zeilen.

Besonders in VHDL oder Verilog, nicht wahr? ;-)

> Und wieso kann man eigentlich bei GCC kein "true" und kein "false"
> benützen?

Man kann true und false benutzen, wenn man entweder C++ als
Programmiersprache hat oder bei C entsprechend dem C99-Standard
zuvor den Header <stdbool.h> eingebunden hat.

> Kann mir jemand sonst noch Eigenheiten von GCC nennen.

Das GCC-Manual ist sehr hilfreich im Aufzählen der zahllosen
Erweiterungen gegenüber dem Sprachstandard.  Ansonsten wird erst
einmal vorausgesetzt, dass du die Sprache selbst (die von der ISO
standardisiert worden ist) natürlich kennst.

> Anscheinend hab
> ich eine andere C-Sprache gelernt so mit "printf" oder "if Taster ==
> true".

Das ist Pascal.  In C wäre es, wenn schon, dann:
1
if (Taster == true) ...

Ist aber Unfug.  Offensichtlich ist ja deine Absicht, dass die Variable
Taster vom Typ bool ist (sonst hätte es keinen Sinn, sie gegen true
oder false zu vergleichen), aber ein bool ist natürlich bereits ein
sinnvoller Steuerausdruck für ein if, sodass man dann besser schreiben
kann:
1
if (Taster) ...

Der zusätzliche Vergleich gegen true bringt rein gar nichts außer mehr
Schreibaufwand, besser lesbar oder irgendwie ,,richtiger'' wird die
Formulierung dadurch nicht.

printf gehört zu stdio.  Da du aber (offenbar) auf einem AVR arbeitest,
der keine klassische ,Bedienconsole' hat wie ein Hostcomputer, musst
du vor der Benutzung erst einmal ein wenig Arbeit investieren um dem
stdio zu sagen, womit es denn sein stdout umsetzen soll (Ausgabe
auf LCD, Ausgabe auf UART, Übertragung über Funkmodul, ...).  Wie das
geht, steht im Handbuch der avr-libc, denn stdio ist Sache der
(Standard-)Bibliothek.

von P. S. (Gast)


Lesenswert?

Mathias Obetzhauser wrote:

> Ich hab überall geguckt, hab aber nichts brauchbares gefunden. Das kann
> doch nicht so schwer fallen sein, eine Flankenerkennung ein zu baue. In
> anderen Programmiersprachen ist das so einfach, da sind es nur 2-3
> Zeilen.

Beispiel?

> Kann mir jemand mal bitte helfen.

Eine Taste per Software entprellen ist so schwer ja nun auch nicht. 
Primitiver Ansatz: Die Taste einfach mit einem Delay, der laenger ist 
als die Prellzeit aber kuerzer als die kuerzeste Drueckzeit, 2 mal 
abfragen. Ist der Zustand in diesem Zeitraum gleich, hast du einen 
zuverlaessigen Wert, den du verarbeiten kannst.

> Und wieso kann man eigentlich bei GCC kein "true" und kein "false"
> benützen?

Geht gut bei mir. Wie waer's mal mit einem uebersetzbaren Code-Beispiel, 
dass deine Probleme aufzeigt?

von Mathias O. (m-obi)


Lesenswert?

Beispiel für Erkennung einer steigenden Flanke:
1
R_TRIG_1(CLK:=Taster);
2
Taster_R:=R_TRIG_1.Q;

Die Variable Taster ist letztendlich der Eingang wo man wissen, wann 
eine steigende Flanke da ist. Und die Variable Taster_R wird kurz high 
wenn eine steigende Flanke erkannt wurde. R_TRIG ist dafür der 
Funktionsbaustein. So in etwa möchte ich das auch haben. Dies ist 
geschrieben in ST (Strukturierter Text) und wird verwendet beim 
programmieren von SPSen.


Mein eigentliches Anliegen ist: mit einem Taster eine LED an- und 
ausschalten, wie eine Art Stromstoßrelais.

von Nubsi (Gast)


Lesenswert?

ALTAAA!!! Ne SPS is auch was ganz anderes! Du vergleichst hier Äpfel mit 
Bauklötzen!

von Mathias O. (m-obi)


Lesenswert?

Wieso sollte nen SPS was anderes sein, da steckt auch nur ein µC drin. 
Die SPS wandelt das was du schreibst auch nur in C um.

von Trohl (Gast)


Lesenswert?

Wenn du kein Bock auf C lernen hast, dann lass es halt und bleib bei ST.
Wenn du aber doch C lernen möchtest, dann musst du auch akzeptieren, 
dass es eine andere Sprache ist, und dich nicht beschweren, dass nun 
aufeinmal alles anders ist als in ST!

von P. S. (Gast)


Lesenswert?

Dann zeig uns doch mal den C-Code zu obigem Beispiel. Dann hast du 
eigentlich schon deine Funktion um Taster zu entprellen, oder nicht?

von Mathias O. (m-obi)


Lesenswert?

Wieso entprellen, mir gehts erstmal ums erkennen einer steigenden 
Flanke. Und ich hab Lust C zu programmieren, sonst würde ich mich damit 
doch nicht rumschlagen. Ich wollte ja nur wissen ob es da eine Funktion 
bzw. Baustein für gibt sowie bei ST.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

SPS-Programmiersprachen sind einfach mal eine Abstraktionsebene höher
angesiedelt als C.

von P. S. (Gast)


Lesenswert?

Auf "keine Lust" reagiert mein Chef immer etwas allergisch. Vor allem, 
wenn er das Gefuehl hat, ich habe keine Lust zum Denken.

bool NewState = INPUT_PIN;
bool TriggerUp = ( LastState == 0) && ( NewState == 1);
LastState = NewState;

Vieleicht habe ich da ja irgendwas nicht verstanden, aber ich bin ja nur 
Informatiker...

von Mathias O. (m-obi)


Lesenswert?

Ich hab doch gesagt das ich Lust habe...
Außerdem wollte ich nur wissen ob jeand sowas schonmal gemacht hat bzw. 
ob es dafür eine Funktion gibt.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Mathias Obetzhauser wrote:

> Außerdem wollte ich nur wissen ob jeand sowas schonmal gemacht hat bzw.
> ob es dafür eine Funktion gibt.

Ja, gibt es, wie dir bereits mehr als einer geschrieben hat: die
Methode heißt Tastenentprellung.  Wenn du diese hast (such danach),
und wenigstens das Prinzip verstanden hast, dann ergibt sich die
Taste-Gedrückt-Erkennung praktisch von allein.

von Trohl (Gast)


Lesenswert?

> ob jeand sowas schonmal gemacht

Nein, da die Sprach brandneu ist, hat das noch nie jemand gemacht. Über 
einfach Addition sind die meisten C-Programmierer noch nicht hinaus.

von Stefan (Gast)


Lesenswert?

Hallo!

nur mal Grundsätzlich, ne SPS wird eigentlich interpretiert, Analog 
Java..., da wird nix in maschinensprache umgesetzt.


so kenn ich das.

Gruß Stefan

von Mathias O. (m-obi)


Lesenswert?

Ich brauche erstmal keine Tastenentprellung, ich will nur den Taster 
abfragen   ob er von 0 nach 1 gewechselt ist oder 1 nach 0. Ich will 
nicht die Zustände 1 oder 0 abfragen. Wie zb bei einer 
Zweihand-Verriegelung. Da wird auch abgefragt ob eine Steigende Flanke 
da war oder nicht. Sonst könnte man ja einfach auf die Taster Tesafilm 
kleben und das wärs. Nur dann ergibt die Verriegelung kein Sinn mehr.

von Mathias O. (m-obi)


Lesenswert?

Eine Tastenentprellung kann man einfach mit einer Einschaltverzögerung 
realisieren.

von Martin Schneider (Gast)


Lesenswert?

Im Prinzip ist deine Frage doch schon beantwortet worden!
Sogar mit einem Code-Beispiel!

Im Gegensatz zur SPS ist der µC vermutlich deutlich schneller und erfaßt 
deshalb auch das mechanische Tasten-Prellen - du drückst einmal und der 
µC sieht 2-5 mal eine Flanke...
Dadurch ist es eher Zufall, ob die simple Flankenerkennung ein 
funktionierendes Tast-Relais produzieren kann.

Aber: Du willst lernen, also bau' dir diese Funktionalität schrittweise 
auf und erfahre selbst, wo die Probleme stecken.

Also erstmal "Taste gedrückt --> LED toggelt",
dann Flankenerkennung dazu,
dann die richtige Entprellung ("bullet-proof" v. Peter Danegger, kann 
ich sehr empfehlen)

Viel Spaß!

Ahoi, Martin

von Der Taster (Gast)


Lesenswert?

Hier mal etwas das toggelt und das Tastenprellen schön zeigt.

Taster an PORTB0 gegen GND
Eine LED von +5V mit Vorwiderstand an PORTB6
Eine LED von +5V mit Vorwiderstand an PORTB7
MCU: Irgend einen Atmel

/* Toggel-Taster */
#include <avr/io.h>

int main(void)
{
  DDRB  |= (1<<DDB6)|(1<<DDB7); // PB6 und PB7 als Ausgang Rest Eing.
  PORTB |= (1<<PB0);            // internen Pull-Up an PB0 aktivieren
  PORTB |= (1<<PB6);            // LED6 aus, LED7 an

  while(1)
  {
    if (!(PINB & (1<<PINB0)))
    {
      PORTB ^= (1<<PB6);  // LED an Port PB6 an bzw. ausschalten
      PORTB ^= (1<<PB7);  // LED an Port PB7 an bzw. ausschalten
    }
  }
}

von P. S. (Gast)


Lesenswert?

Da sollte aber noch ein Delay rein, sonst dimmt das nur ein bisschen 
beide LEDs ;-)

von Der Taster (Gast)


Lesenswert?

Nix delay.
Probier's aus.
Die LEDs werden wechselseitig umgeschaltet.
Welche dann leuchten bleibt hängt vom prellen ab.

von Der Taster (Gast)


Lesenswert?

Wenn der Taster gedrückt bleibt leuchten beide LEDs natürlich etwas 
dunkler, als eine allein. Auch abhängig von der Taktfrquenz. Hier 4MHz.

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.