Forum: Mikrocontroller und Digitale Elektronik AVR - Pin-Abfrage invertieren


von jow (Gast)


Lesenswert?

Hallo!

Bei
if ( PINA && ( 1 << PINA0 ) ) { }
wird der Funktionsblock ausgeführt, wenn Pin A0 auf HI liegt.

Der Funktionsblock soll aber nur ausgeführt werden, wenn Pin A0 auf LO 
liegt.

Das kann man vermutlich erreichen, wenn man die Abfrage invertiert.

Geht das möglicherweise so?

if (!(PINA && ( 1 << PINA0 )) ) { }

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


Lesenswert?

jow schrieb:
> Geht das möglicherweise so?
Ich würde das einfach ausprobieren...

> Geht das möglicherweise so?
Ja.

von U. C. (Gast)


Lesenswert?

if (!(PINA & ( 1 << PINA0 )) ) { }

von Marc S. (marc_s86)


Lesenswert?

da ist ein und zu viel denke ich. ansonsten sollte das klappen

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


Lesenswert?

Marc S. schrieb:
> da ist ein und zu viel denke ich.
Richtig, und insofern stimmt auch diese Abfrage nicht, die
jow schrieb:
> if ( PINA && ( 1 << PINA0 ) ) { }
Denn hier wird der Funktionsblock immer ausgeführt, wenn mindestens ein 
Pin von PINA high ist...

von jow (Gast)


Lesenswert?

Vielen Dank für die schnellen Antworten!

Lothar M. schrieb:
>> if ( PINA && ( 1 << PINA0 ) ) { }
> Denn hier wird der Funktionsblock immer ausgeführt, wenn mindestens ein
> Pin von PINA high ist...

Das zweite & war ein Tippfehler - Danke für den Hinweis und die 
Erklärung!!!

von Tom (Gast)


Lesenswert?

jow schrieb:
> if ( PINA && ( 1 << PINA0 ) ) { }

Das Nachdenken über den negierten Ausdruck kannst Du auch dem Compiler 
überlassen:
1
bool pin_is_high =  PINA & ( 1 << PINA0 ) ;
2
if (!pin_is_high)
3
{
4
    // ......
5
}
Das ist auch für die Nachwelt (Du in 2 Wochen ;) ) etwas lesbarer.

von jow (Gast)


Lesenswert?

Da hast du wahr!

;O)

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


Lesenswert?

Tom schrieb:
> Das Nachdenken über den negierten Ausdruck kannst Du auch dem Compiler
> überlassen
Ich würde mich aber nicht unbedingt darauf verlassen, dass der das dann 
auch immer sauber rausoptimiert...

Wenn schon, dann würde ich das über ein #define machen:
1
#define pinA0_is_high (PINA & (1<<PINA0))
2
3
....
4
5
if (!pinA0_is_high)
6
{
7
    // ......
8
}

: Bearbeitet durch Moderator
von U. C. (Gast)


Lesenswert?

Lothar M. schrieb:
1
> #define pinA0_is_high (PINA & (1<<PINA0))
2
> 
3
> ....
4
> 
5
> if (!pinA0_is_high)
6
> {
7
>     // ......
8
> }

-------------
1
#define pinA0_is_low (PINA | (1<<PINA0))
2
3
....
4
5
if (pinA0_is_low)
6
{
7
    // ......
8
}
Immer positiv denken!
;-)

von Werner (Gast)


Lesenswert?

jow schrieb:
> Bei
> if ( PINA && ( 1 << PINA0 ) ) { }
> wird der Funktionsblock ausgeführt, wenn Pin A0 auf HI liegt.
>
> Der Funktionsblock soll aber nur ausgeführt werden, wenn Pin A0 auf LO
> liegt.

Liebe Leute,

der TO hat doch geschrieben:
WENN PA0 == LOW,
DANN mache irgendwas.

Eine Anfrage a la
if (!(PINA & ( 1 << PINA0 )) ) { }

bedeutet aber:
WENN irgendetwas anderes außer PA0 Low ist
DANN mache was.

Sobald mann zwei Eingänge (z.B. Taster, die nach GND schalten) getrennt 
voneinander beutzen will gibt es hier jawohl ein Problem.

Richtig wäre in dem Fall:

if (~PINA & ( 1 << PINA0 )) ) { }

Werner

von Werner (Gast)


Lesenswert?

Werner schrieb:
> bedeutet aber:
> WENN irgendetwas anderes außer PA0 Low ist
> DANN mache was.

"WENN irgendetwas anderes außer PA0 High ist"

meinte ich natürlich

Werner

von Tom (Gast)


Lesenswert?

U. C. schrieb:
> #define pinA0_is_low (PINA | (1<<PINA0))

Werner schrieb:
> Eine Anfrage a la
> if (!(PINA & ( 1 << PINA0 )) ) { }
> [bedeutet]
> "WENN irgendetwas anderes außer PA0 High ist"


Das bestätigt ein klein wenig den Vorschlag, das nicht schwierige, aber 
unübersichtliche Invertieren von Bedingungen (egal ob man die 
ursprüngliche Bedingung jetzt in einer dokumentierenden 
Zwischenvariablen, einem Makro oder einer Funktion versteckt) besser dem 
Compiler zu überlassen.

von Falk B. (falk)


Lesenswert?

@ Werner (Gast)

>> Der Funktionsblock soll aber nur ausgeführt werden, wenn Pin A0 auf LO
>> liegt.

>der TO hat doch geschrieben:
>WENN PA0 == LOW,
>DANN mache irgendwas.

Stimmt.

>Eine Anfrage a la
>if (!(PINA & ( 1 << PINA0 )) ) { }

>bedeutet aber:
>WENN irgendetwas anderes außer PA0 Low ist
>DANN mache was.

Stimmt nicht. Siehe Bitmanipulation.

>Sobald mann zwei Eingänge (z.B. Taster, die nach GND schalten) getrennt
>voneinander beutzen will gibt es hier jawohl ein Problem.

Nö.

>Richtig wäre in dem Fall:
>if (~PINA & ( 1 << PINA0 )) ) { }

Nö, das wäre nur der Fall, wenn du deinen LOW aktiven Taster per 
Software als HIGH aktiv auswerten willst.

von jow (Gast)


Lesenswert?

Werner schrieb:
> Eine Anfrage a la
> if (!(PINA & ( 1 << PINA0 )) ) { }
>
> bedeutet aber:
> WENN irgendetwas anderes außer PA0 Low ist
> DANN mache was.

Bei mir im Programm funktioniert es tadellos mit drei verschiedenen 
A-Pins gleichzeitig.


Falk B. schrieb:
>>Richtig wäre in dem Fall:
>>if (~PINA & ( 1 << PINA0 )) ) { }
>
> Nö, das wäre nur der Fall, wenn du deinen LOW aktiven Taster per
> Software als HIGH aktiv auswerten willst.

So ganz verstehe ich das nicht. Kann man das an einem konkreten Beispiel 
aufzeigen?

von Falk B. (falk)


Lesenswert?

@ jow (Gast)
>>>if (~PINA & ( 1 << PINA0 )) ) { }
>> Nö, das wäre nur der Fall, wenn du deinen LOW aktiven Taster per
>> Software als HIGH aktiv auswerten willst.

>So ganz verstehe ich das nicht. Kann man das an einem konkreten Beispiel
>aufzeigen?

Ganz einfach. Meist sind Taster low aktiv angeschlossen, so wie hier.

https://www.mikrocontroller.net/articles/AVR-Tutorial:_IO-Grundlagen#Hardware

Taste nicht gedrückt -> Input Bit = 1
Taste       gedrückt -> Input Bit = 0

Wenn man das intern alles auf high aktive Logik umwandlen will, 
invertiert man einfach PINx beim Lesen. Damit ist alle Logik in der 
Software high aktiv und man muss nicht immer umdenken.

if (~PINA & ( 1 << PINA0 )) { /*PA0 Taste gedrückt*/ }

von jow (Gast)


Lesenswert?

Jetzt habe ichs, Danke Falk für die gute Erklärung!!!

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.