Forum: Mikrocontroller und Digitale Elektronik AVR, 2 Eingänge gleichzeitig abfragen in C?


von Daniel L. (dannynrw)


Lesenswert?

Hi Leutz,
bislang war die IF-Abfrage mit einem Eingang eigentlich nie ein Problem, 
aber nun möchte ich gerne 2 Eingänge gleichzeitig abfragen. Nur wenn 
BEIDE Eingänge 1-Signal haben, soll ein Ausgang geschaltet werden.
Dabei sollen natürlich die restlichen Bits nicht in die Auswertung mit 
einfließen, da diese ebenfalls durch Eingangssignale veränderbar sind.
Folgende Zeile schaltet scheinbar schon den Ausgang, wenn einer der 
beiden Eingänge ein 1-Signal hat:

if (PIND & 0b00010010)
{
PORTB|= (1 << PB0);
}

Habe auch noch einige andere Befehlszeilen ausprobiert, aber scheinbar
scheine ich die Auswertung noch nicht richtig verstanden zu haben.
Wäre hier für nen Tipp dankbar.
Daniel

von Noname (Gast)


Lesenswert?

1
if ((PIND & 0b00010010) == 0b00010010)
2
{
3
      PORTB|= (1 << PB0);
4
}

von Noname (Gast)


Lesenswert?

Lies Dir nochmal in einem C-Buch durch was genau
1
if(x) ...
2
if (x & y) ...

macht.

Da

von Dussel (Gast)


Lesenswert?

Der if-Block wird ausgeführt, wenn die Bedingung wahr ist, in C, wenn 
der ausgewertete Ausdruck nicht 0 ist. Wenn jetzt einer der beiden 
Eingänge 1 ist, ist das Ergebnis des Und größer als 1 und damit wahr. In 
deinem Fall könntest du zum Beispiel schreiben:
1
if(PIND&0b00010010==18)
2
{
3
}
Wenn beide Eingänge 1 sind, ist das Ergebnis genau 18.

Eine verständlichere Möglichkeit wäre:
1
if((PIND&0b00010000)&&(PIND&000000010))
2
{
3
}

von Karol B. (johnpatcher)


Lesenswert?

Wobei man bei der von Noname geposteten Lösung darauf hinweisen sollte, 
dass dies so nicht Standardkonform ist und "nur" mit dem avr-gcc 
funktioniert. Im Normalfall wird man daher die Hex-Notation verwenden.

von Wolfgang (Gast)


Lesenswert?

Noname schrieb:
Wahrscheinlich möchtest du deinen Ausgang irgendwann auch wieder 
ausschalten. Dann könnte
1
PORTB &= ~(1 << PB0);
ganz nützlich sein ;-)

von Noname (Gast)


Lesenswert?

@ Karol Babioch
>Wobei man bei der von Noname geposteten Lösung darauf hinweisen sollte,
>dass dies so nicht Standardkonform ist und "nur" mit dem avr-gcc
>funktioniert. Im Normalfall wird man daher die Hex-Notation verwenden.

Meine Lösung wirft das Problem nicht auf. Es besteht es schon im vom TO 
geposteten Code. Das eigentlich ursächliche Problem hat damit garnichts 
zu tun.

von Daniel L. (dannynrw)


Lesenswert?

Danke erstmal für die schnellen Antworten.
An die Dezimalauswertung habe ich auch schon gedacht, habe aber heute 
nicht soweit gedacht, daß die 18 hier eigentlich nur durch eben DIESE 
EINE Konstellation möglich ist.
Allen noch einen schönen (hoffentlich sonnigen) (Fußball)sonntag :-).
Daniel

von Noname (Gast)


Lesenswert?

Da haben wir es. Jetzt ist er auf einer falschen Spur.

Das Problem, Danny ist nicht ob Dezimal, Hexdezimal oder Binär.

Das Problem ist, das Du nicht verstanden hast, was
1
if(x) ...
2
if (x & y) ...

eigentlich macht.

Die Bedingung "x" ist dann wahr, wenn x ungleich 0 ist. Das ist aber für 
drei der vier möglichen Kombinationen Deines Ports wahr (lässt man die 
restlichen 6 Bits ausser Acht).
Du willst hingegen auf EINE Kombination hin testen. Also musst Du nicht 
nur die beiden Bits mit & ausmaskieren sondern noch das Ergebnis prüfen.

Ob Dezimal oder was auch immer ist hier am Rande interessant.

von Daniel L. (dannynrw)


Lesenswert?

Du hast Recht Noname,
daher kam natürlich dann bei meiner ersten Zeile schon der Ausgang als 
nur ein Eingang 1-Signal lieferte. Die erste Verknüpfung (PIND & 
0b00010010)
ist also in dem Falle, wenn ich das nun richtig verstanden habe, nur ein 
Ausmaskieren der Bits.

Angenommen, PIND hätte momentan den Zustand 11111111:
Wäre also:
  11111111
& 00010010
= 00010010

Mein vorheriges Ergebnis "vergleichst" Du ja nochmals mit dem 
==0b00010010.
Und dieses wird eben nur wahr, wenn 0b00010010 == 0b00010010.

Danke Dir :-).

von Daniel L. (dannynrw)


Lesenswert?

Habe gerade nochmal mein Buch herausgekramt und dort steht es so auch.
Zitat:

"In Verbindung mit der Programmiersprache C ist alles wahr, was einen 
Wert ungleich 0 besitzt. Dagegen wird unwahr zurückgeliefert, wenn der 
Wert gleich 0 ist. Zwischenwerte gibt es nicht, eine Bedingung ist stets 
wahr oder unwahr..."

von Jannik O. (jannipanni)


Lesenswert?

Würde es genauso machen wie Noname

if ((PIND & 0b00010010) == 0b00010010)
{
      PORTB|= (1 << PB0);
}

Relevante pins mit & heraussuchen und mit == vergleichen.

von Wolfgang (Gast)


Lesenswert?

Daniel Lo schrieb:
> ""... Zwischenwerte gibt es nicht, eine Bedingung ist stets
> wahr oder unwahr..."

Na, das ist doch mal 'ne klare Aussage, die man sich über'n Monitor 
hängen kann. Fuzzylogik lassen wir jetzt mal außen vor, damit die 
gewonnene Klarheit nicht gleich wieder flöten geht ;-)

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.