Forum: Compiler & IDEs Bitoperanden "C"


von Norbert63 (Gast)


Lesenswert?

Hallo Freunde der Elektronik (:

Was mir noch nicht ganz klar scheint ist folgendes... (für euch 
sicherlich ganz klar :-P)


PORTD |= (1<<PD1) | (1<<PD2;...

Warum schreibt man vor dem gleichheitszeichen noch mal ein "OR" ?

--

Augenkrebsüberschrift geändert
-rufus

von Mark B. (markbrandis)


Lesenswert?

PORTD |= was_auch_immer;

ist eine Kurzschreibweise für:

PORTD = PORTD | was_auch_immer;

von Norbert63 (Gast)


Lesenswert?

also kann ich quasie..


PORTX |= (1<<PX) ; (1<<PX)

anstatt


PORTX = (1<<PX) | (1<<PX)...


?

von Amateur (Gast)


Lesenswert?

Nein!

Wer Augen hat, der schaue.

von kläb (Gast)


Lesenswert?

Norbert63 schrieb:
> also kann ich quasie..
>
> PORTX |= (1<<PX) ; (1<<PX)
>
> anstatt
>
> PORTX = (1<<PX) | (1<<PX)...
>
> ?

Nö, das geht nicht.

Der Unterschied zwischen den richtigen Varianten:
1
PORTX  = (1<<PX1) | (1<<PX2); //Feste Zuweisung wie A=1;
2
PORTX |= (1<<PX1) | (1<<PX2); //Read-Modify-Write.
3
//Zuerst den Wert des Registers auslesen dann die neuen Bits setzen dann zurueckschreiben.

siehe auch:
Bitmanipulation

von N. G. (newgeneration) Benutzerseite


Lesenswert?

Nein, des ergibt einen Fehler

Warum nicht einfach so machen wie es gegeben ist?
Siehe auch Bitmanipulation

Wenn du schreiben würdest
1
PORTX = (1<<PX1)|(1<<PX3);
würdest du nur die Bits 1 und 3 setzen, unabhängig von dem 
Ursprungszustand.
Mit
1
PORTX |= (1<<PX1)|(1<<PX3);
2
//oder
3
PORTX = | PORTX (1<<PX1)|(1<<PX3);
setzt du nur die bits 1 und 3, alle anderen werden belassen

von Fugger (Gast)


Lesenswert?

@ Norbert63

Aber nein. Du musst Dir angewöhnen in Mustern zu denken.

Mark schrieb, dass

PORTD |= was_auch_immer;

und

PORTD = PORTD | was_auch_immer;

die gleiche Bedeutung haben.

Hast Du also den Ausdruck

PORTD |= (1<<PD1) | (1<<PD2);

vorliegen, dann steht was_auch_immer für "(1<<PD1) | (1<<PD2)".

und nicht für "(1<<PD1)".

Daraus folgt, dass

PORTD |= (1<<PD1) | (1<<PD2);

gleichbedeutend mit

PORTD = PORTD | (1<<PD1) | (1<<PD2);

ist.


Eine umfassendere und detailliertere Erklärung findest Du in einem 
C-Buch.

von Norbert63 (Gast)


Lesenswert?

Danke Fugger ;)

Das ist doch mal eine schöne Erklärung...

Damit spare ich mir quasie einmal den Port zu schreiben ;)
Das wollte ich doch wissen.

vielen dank ;)

von Fugger (Gast)


Lesenswert?

Bitteschön.

von N. G. (newgeneration) Benutzerseite


Lesenswert?

> Damit spare ich mir quasie einmal den Port zu schreiben ;)

Schau dir mal das erzeugte .lss-File an. Dort siehst du, dass des keinen 
Unterschied macht, ob du
1
PORTX |= (1<<PX1)|(1<<PX3);
2
//oder
3
PORTX = | PORTX (1<<PX1)|(1<<PX3);
schreibst. Der Copmiler übersetzt das schon gut genug. Manchmal hilft 
es, auch ein bisschen Asm zu verstehen(ich kanns auch nicht schreiben, 
aber halt größtenteils lesen).
Aber wenn du es nun verstanden hast ist alles in Ordnung, sofern du ein 
C-Buch gelesen oder wenigstens den oben schon 2mal genannten Artikel 
durchgelesen hast

von Karl H. (kbuchegg)


Lesenswert?

Norbert63 schrieb:
> Danke Fugger ;)
>
> Das ist doch mal eine schöne Erklärung...
>
> Damit spare ich mir quasie einmal den Port zu schreiben ;)

Nö.


Es ist der Unterschied zwischen

* eine Kiste Bier erst mal ausleeren um dann 2 Flaschen reinzustellen
* zusätzlich zu den bereits in der Kiste vorhandenen leeren Flaschen 
noch 2 Flaschen mit dazu hineinstellen

Und das ist ein deutlicher Unterschied.
In dem einen Fall sind garantiert nur 2 leere Flaschen in der Kiste. Im 
anderen Fall hängt es davon ab, was vorher schon drinn war.

von kläb (Gast)


Lesenswert?

N. G. schrieb:
>> Damit spare ich mir quasie einmal den Port zu schreiben ;)
>
> Schau dir mal das erzeugte .lss-File an. Dort siehst du, dass des keinen
> Unterschied macht, ob duPORTX |= (1<<PX1)|(1<<PX3);
> //oder
> PORTX = | PORTX (1<<PX1)|(1<<PX3);
> schreibst. Der Copmiler übersetzt das schon gut genug. Manchmal hilft
> es, auch ein bisschen Asm zu verstehen(ich kanns auch nicht schreiben,
> aber halt größtenteils lesen).
> Aber wenn du es nun verstanden hast ist alles in Ordnung, sofern du ein
> C-Buch gelesen oder wenigstens den oben schon 2mal genannten Artikel
> durchgelesen hast

Und da ist ein Fehler drin.

von Rolf Magnus (Gast)


Lesenswert?

Karl Heinz schrieb:
> Norbert63 schrieb:
>> Danke Fugger ;)
>>
>> Das ist doch mal eine schöne Erklärung...
>>
>> Damit spare ich mir quasie einmal den Port zu schreiben ;)
>
> Nö.

Doch. Bei
1
PORTX = PORTX | irgendwas;
muß er PORTX zweimal hinschreiben, bei
1
PORTX |= irgendwas;
nicht. Ich glaube, daß das damit gemeint war, und nicht daß er sich 
irgendeinen Schreibzugriff spart.

von Dirk B. (dirkb2)


Lesenswert?

Norbert63 schrieb:
> Damit spare ich mir quasie einmal den Port zu schreiben

Und man sieht auf einen Blick, dass du denselben Port bearbeitest.

von Marc P. (marcvonwindscooting)


Lesenswert?

> > Damit spare ich mir quasie einmal den Port zu schreiben ;)
> Nö.

Ich w"urde es jetzt - ohne alle m"oglichen C-Standards zu w"alzen - so 
sehen:
Es sind 2 prinzipiell verschiedene Sachen die auf einigen Prozessoren 
zufaellig das gleiche Ergebnis liefern.

Wenn der Prozessor eine Instruktion besitzt, die einen Speicherwerte 
'verodert' dann wird der Compiler f"ur |= diese nehmen. Sonst macht er 
ein read-modify-write stattdessen. So und da haben wir einen 
fundamentalen Unterschied: 1. Fall: atomar, 2. Fall nicht atomar.

Meistens ist das egal.

Weiss ein Compilerexperte hier zuf"allig aus dem Stehgreif, was der 
Compiler machen muss, sollte zu allem "Ubel die Linke Seite 'volatile' 
sein?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Dieses Forum unterstützt übrigens schon seit langem UTF-8, es ist also 
absolut überhaupt nicht erforderlich, im 7-Bit-Zeitalter zu verharren.

von Marc P. (marcvonwindscooting)


Lesenswert?

Rufus Τ. Firefly schrieb:
> absolut überhaupt nicht erforderlich, im 7-Bit-Zeitalter zu verharren.

'"' == 34 (mind. 6bit)

Hat aber nix mit Wort-breiten zu tun!
Und deshalb hab auch keinen Intel 4004 :)

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Ich bezog mich auf Deine anstrengend antiquierte Art der 
Umlautschreibweise.

von Ich (Gast)


Lesenswert?

Norbert63 schrieb:
> also kann ich quasie..
>
> PORTX |= (1<<PX) ; (1<<PX)
>
> anstatt
>
> PORTX = (1<<PX) | (1<<PX)...

Moment:
Ist doch bei AVR im Ergebnis das gleiche.

Im ersten Fall wird ausgelesen, gesetzt (wenn vorher 0)im zweiten Fall 
gleich gesetzt.
Da das Ziel ist, nur 2 Bits zu setzten, kann ich mir das vorherige 
Auslesen doch sparen. Eine Eins rein und fertig, egal was vorher drin 
stand.
Die restlichen Bits bleiben in beiden Fällen doch unbearbeitet.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> Die restlichen Bits bleiben in beiden Fällen doch unbearbeitet.

Nein. Sie werden auf 0 gesetzt.

Warum sollte eine Zuweisung nur auf 1 gesetzte Bits berüchsichtigen?

von Ich (Gast)


Lesenswert?

ok. alles klar. Danke.

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.