Hey zusammen, einen schönen Sonntag wünsche ich! Ich möchte eine Schützüberwachung realisieren, sprich feststellen wenn ein angesteuertes Schütz entweder kleben bleibt oder nicht anzieht. Das Schütz wird mit log.1 angesteuert, der Eingang liefert bei Ansteuerung log.0. Eigentlich ganz einfach dachte ich. Denn wenn beide Signale log.1 sind oder beide log.0 sind liegt ein Fehler vor (natürlich wird die Ansprechzeit des Schützes berücksichtigt). Ich dachte diese Zeile wär der Schlüssel zum Erfolg... if( (PINB & (1<<PB2)) == (PINC & (1<<PC0)) ) ...aber die Geschichte klappt nur beim klebenbleiben des Schützes, sprich Ausgang=0 und Eingang=0 (angesteuert). Für den entgegengesetzten Fall klappt es nicht... Ich habe alle möglichen Umstellungen, XOR mit Negierung probiert, sehe aber nun nach 1,5 Std den Wald vor lauter Bäumen nicht mehr. Hat jemand von Euch einen Tipp für mich? Danke und Gruß Danny
Hallo, passt doch alles... (PINB & (1<<PB2)) ergibt 0x00000100 (PINC & (1<<PC0)) ergibt 0x00000001 warum sollte da ein Vergleich wahr werden? Ich vermute jetzt mal, Du findest selbst eine Lösung? Gruß aus Berlin Michael
(PINB & (1<<PB2) ist entweder 0 oder 4, je nach Zustand des Bits. (PINC & (1<<PC0) ist entweder 0 oder 1, je nach Zustand des Bits. Jetzt klarer, warum deine Zeile nicht funktioniert? Wenn du auf logische Gleichheit prüfen willst, muss beides auf 0/1 reduziert werden.
ich war der Meinung bei das beim Vergleich (==) der Ausdruck in den Klammern in 0/1 umgesetzt, bzw. so gewertet wird... und nun fragt bitte nicht warum :) wie schaut denn für diesen Fall eine elegante Lösung aus? Folgendes ist denke ich leicht verständlich und funktioniert aber platt gefragt: "macht man das so"? :) if( ((PINB & (1<<PB2))>>PB2) == (PINC & (1<<PC0)) )
Viele Wege führen nach Rom:
1 | (PINB&(1<<PB2))>>PB2 |
2 | (PINB&(1<<PB2))?1:0 |
3 | !!(PINB&(1<<PB2) |
4 | (PINB&(1<<PB2))==(1<<PB2) |
5 | (PINB&(1<<PB2))!=0 |
6 | (PINB&(1<<PB2))>0 |
7 | (_Bool)(PINB&(1<<PB2)) |
Nimm einfach den, der dir am besten gefällt.
Viel andere Möglichkeiten hast du in C nicht (Das meiste von Stefan ist umgestellt), außer irgendetwas exotisches:
1 | if((PINB | PINC) & ((1<<PB2)|(1<<PC0)) - 1 >= 4) //PB2 == PC0 |
Samuel K. schrieb: > Das meiste von Stefan ist umgestellt Was meinst du damit? Das sind alles Möglichkeiten, um die linke Seite des == von 0/4 auf 0/1 zu reduzieren.
Was spricht dagegen, einfach alles zur 1 zu shiften?
1 | if( (PINB >> PB2)&1) == (PINC >>PC0) &1 ) |
Das scheint mir die kürzeste Variante zu sein.
Stefan Ernst schrieb: > Was meinst du damit? Das sind alles Möglichkeiten, um die linke Seite > des == von 0/4 auf 0/1 zu reduzieren. Das gleiche Prinzip. Das Grundgerüst der Prüfung (=Vergleich der Bits) bleibt gleich.
Samuel K. schrieb: > Das gleiche Prinzip. Das Grundgerüst der Prüfung (=Vergleich der Bits) > bleibt gleich. Achso. Jedenfalls funktioniert dieses "Grundgerüst" wenigstens, im Gegensatz zu deiner Lösung. ;-)
Hey, vielen Dank für Eure schnelle Hilfe! Ich habe es nun beim >>PB2 gelassen, nun wirds wenigstens ein entspannter Abend :)
Leute, Leute, Leute. Code muss selbsterklärend sein! Was spricht gegen:
1 | if ( ((PINB & (1<<PB2)) && (PINC & (1<<PC0))) |
2 | || !((PINB & (1<<PB2)) && !(PINC & (1<<PC0))) ) |
3 | {
|
4 | Alles in Ordnung |
5 | }else |
6 | {
|
7 | Unterschiedlich
|
8 | }
|
Ist allerdings ungetestet.
Ersetze das && durch || und es funktioniert. Ich finde es kryptischer. Ich finde Code sollte kurz sein, dann muss man weniger lesen.
Samuel K. schrieb: > Ersetze das && durch || und es funktioniert. Nein, das passt schon so, außer dass das erste ! etwas verrutscht ist. !(( -> (!(
Simon K. schrieb: > Leute, Leute, Leute. Code muss selbsterklärend sein! "selbsterklärend" liegt aber zum Teil auch im Auge des Betrachters. ;-) Ich würde z.B. folgende Variante als noch "selbsterklärender" favorisieren:
1 | if ((_Bool)(PINB & (1<<PB2)) == (_Bool)(PINC & (1<<PC0))) |
Stimmt, ich war irgendwie beim bitweisen &. Da fällt mir ein: Warum nicht kompliziert? Dann lernt man wenigstens komplizierter zu denken.
Stefan Ernst schrieb: > Simon K. schrieb: >> Leute, Leute, Leute. Code muss selbsterklärend sein! > > "selbsterklärend" liegt aber zum Teil auch im Auge des Betrachters. ;-) > > Ich würde z.B. folgende Variante als noch "selbsterklärender" > favorisieren: >
1 | if ((_Bool)(PINB & (1<<PB2)) == (_Bool)(PINC & (1<<PC0))) |
Und was ist _Bool? Wo gibt es den Datentyp? Und zwar in einer derartigen Definition, dass er das von dir gewünschte Verhalten erzeugt?
Samuel K. schrieb: > Stimmt, ich war irgendwie beim bitweisen &. > > Da fällt mir ein: Warum nicht kompliziert? Dann lernt man wenigstens > komplizierter zu denken. Aus einem einfachen Grund: Wartbarkeit. Wenn man irgendwann mal wieder nach ein paar Jahren was ändern oder debuggen möchte und dann sowas sieht:
1 | (PINB&(1<<PB2))>>PB2 |
Dann ist man erst mal damit beschäftigt das Statement zu verstehen. Da das Statement aber nicht viel "Geschäftslogik" in sich verbirgt ist das sinnlos verschwendete Lebenszeit.
Simon K. schrieb: > Und was ist _Bool? Wo gibt es den Datentyp? Und zwar in einer derartigen > Definition, dass er das von dir gewünschte Verhalten erzeugt? Im C-Standard seit C99.
Stefan Ernst schrieb: > Simon K. schrieb: >> Und was ist _Bool? Wo gibt es den Datentyp? Und zwar in einer derartigen >> Definition, dass er das von dir gewünschte Verhalten erzeugt? > > Im C-Standard seit C99. Okay, dann ist die Variante lesbarer. Vorausgesetzt man kennt den _Bool Typen. ;-) Wenn C99, dann sollte der GCC (das gewählte Subforum) das auch unterstützen.
1 | if( !(PINB & (1<<PB2)) == !(PINC & (1<<PC0)) ) |
Die Erklärung ist, der !-Operator liefert 0 (falsch) oder 1 (wahr) als Ausgabe. Als Eingabe gilt aber 0 = falsch, !0 = wahr. Er wandelt also int in bool um. In diesem Fall stört die Negation nicht, da auf beiden Seiten. Profis schreiben oft auch:
1 | if( !!(PINB & (1<<PB2)) == !!(PINC & (1<<PC0)) ) |
Damit entfällt die Negation und man wird mit dem Holzhammer drauf hingewiesen, das bool rauskommen soll. 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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.