Forum: Compiler & IDEs Einzelne Bits setzen


von Andy11 (Gast)


Lesenswert?

Da ich mich gerade in C einarbeite habe ich einmal ein paar Fragen zum 
setzen von Bits in einer uint8_t Variable.

Aus Tutorial:
>#include <avr/io.h>
>...
>#define MEINBIT 2
>...
>PORTA |= (1 << MEINBIT);    /* setzt Bit 2 an PortA auf 1 */
>PORTA &= ~(1 << MEINBIT);   /* loescht Bit 2 an PortA */

Wieso löscht gerade dieser Ausdruck (|=) die Bits und der (&= ~) löscht 
sie?
Ist das eine Festlegung oder haben diese Zeichen irgend einen 
Zusammenhang mit dem Löschen und setzen von Bits?

Wieso geht das nicht einfach so: PORTB.0 = 1, x.5 = 1 ? Wäre das nicht 
logischer?
Ich weiß das geht mit struct aber kann ich mit struct auch einfach sagen

PORTB = x(Variable vom struct und besteht aus 8 Bit)
und jetzt kann ich den PORTB vom x aus steuern?
Leider kann ich noch nicht simulieren da mein Eclipse nicht Debuggen 
kann, deswegen die Fragen.

lg andy

von Wolfgang B. (et-tutorials) Benutzerseite


Lesenswert?

Hallo Andy11,
ich habe zu diesem Thema ein Video gedreht.
Vielleicht hilft es Dir...

http://et-tutorials.de/1908/bitweise-manipulation/

von Rolf Magnus (Gast)


Lesenswert?

Andy11 schrieb:
> Wieso löscht gerade dieser Ausdruck (|=) die Bits und der (&= ~) löscht
> sie?
> Ist das eine Festlegung oder haben diese Zeichen irgend einen
> Zusammenhang mit dem Löschen und setzen von Bits?

Dazu bietet es sich an, ein Buch über die Grundlagen von C zu lesen. Die 
obigen "Zechen" (Operatoren) führen bitweise Boole'sche Operationen 
durch.

> Wieso geht das nicht einfach so: PORTB.0 = 1, x.5 = 1 ? Wäre das nicht
> logischer?

Es würde halt gegen die ISO-C-Spezifikation verstoßen. In C gibt es 
keine Bit-Datentypen.

> Ich weiß das geht mit struct

Du meinst vermutlich Bitfelder.

> aber kann ich mit struct auch einfach sagen
>
> PORTB = x(Variable vom struct und besteht aus 8 Bit)
> und jetzt kann ich den PORTB vom x aus steuern?

PORTB ist vom Typ uint8_t. Dem kann man keine Struktur zuweisen.

> Leider kann ich noch nicht simulieren da mein Eclipse nicht Debuggen
> kann, deswegen die Fragen.

Was würdest du denn simulieren wollen? Deine Ideen wird der Compiler 
schon gar nicht akzeptieren.

von narf (Gast)


Lesenswert?

PORTA |= (1 << MEINBIT)

oder anders ausgedrückt

PORTA = PORTA | (1 << MEINBIT)

dein neues bit wird mit dem alten portwert verodert

bei &=  auch nur wird es vorher negiert und dann verundet

von narf (Gast)


Lesenswert?

asso ..
es gibt welche die haben sowas mit Portx.bit  gebaut
es geht also ...

muss ma gucken .. irgendwo hab ich da noch was

von (prx) A. K. (prx)


Lesenswert?

narf schrieb:

> es gibt welche die haben sowas mit Portx.bit  gebaut
> es geht also ...

Zwei Wege: Der eine geht über Bitfelder und wurde bereits angerissen. 
Kommt sowas wie PORTA.BIT0 = 1 raus. PORTA.0 geht so nicht.

Der andere Weg ist die Verwendung von C als Basis einer eigenen frisch 
erfundenen Programmiersprache mit solchen Erweiterungen wie PORTA.0 = 1, 
die man frecherweise trotzdem C nennt. Nachteil: Portierungsfalle, kommt 
man schlecht wieder von weg.

von Andy11 (Gast)


Lesenswert?

Wolfgang Bengfort schrieb:
> Hallo Andy11,
> ich habe zu diesem Thema ein Video gedreht.
> Vielleicht hilft es Dir...

ok, das Video habe ich mir zwar angeschaut, mir hilft aber das

narf schrieb:
> PORTA |= (1 << MEINBIT)
>
> oder anders ausgedrückt
>
> PORTA = PORTA | (1 << MEINBIT)
>
> dein neues bit wird mit dem alten portwert verodert
>
> bei &=  auch nur wird es vorher negiert und dann verundet

besser.
Ich weiß was |= bedeutet und ich weiß auch warum da was gesetzt wird, 
die Frage ging eher auf das &=~
Was macht die Welle nach dem Gleich?

A. K. schrieb:
> Zwei Wege: Der eine geht über Bitfelder und wurde bereits angerissen.
> Kommt sowas wie PORTA.BIT0 = 1 raus. PORTA.0 geht so nicht.

Genau so habe ich das gemeint. Dann würde ich aber unnötig Speicher 
verschwenden oder?

lg andy

von (prx) A. K. (prx)


Lesenswert?

Andy11 schrieb:

> Dann würde ich aber unnötig Speicher verschwenden oder?

Nur wenn der Compiler dusselig genug ist, diese 1-Bit Bitfelder nicht 
auf die gleiche Art zu behandeln. Versuch macht kluch. Bei GCC m.W. kein 
Problem. Man muss "nur" für jedes vermaledeite I/O-Register so eine 
Bitfeld-Struct definieren.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Andy11 schrieb:
> die Frage ging eher auf das &=~
> Was macht die Welle nach dem Gleich?

Die Tilde invertiert jedes einzelne Bit.

Beispiel:

Bit 3 setzen:

  a |= (1 << 3);

  a |= 0x08;

  a |= 0b00001000;

Bit 3 löschen:

  a &= ~(1 << 3);

  a &= ~0x08;

  a &= ~0b00001000;

  a &= 0b11110111;

von Andy11 (Gast)


Lesenswert?

A. K. schrieb:
> Nur wenn der Compiler dusselig genug ist, diese 1-Bit Bitfelder nicht
> auf die gleiche Art zu behandeln. Versuch macht kluch. Bei GCC m.W. kein
> Problem. Man muss "nur" für jedes vermaledeite I/O-Register so eine
> Bitfeld-Struct definieren.

okay, das ist ja was positives

Rufus t. Firefly schrieb:
> Die Tilde invertiert jedes einzelne Bit.
>
> Beispiel:
>
> Bit 3 setzen:
>
>   a |= (1 << 3);
>
>   a |= 0x08;
>
>   a |= 0b00001000;
>
> Bit 3 löschen:
>
>   a &= ~(1 << 3);
>
>   a &= ~0x08;
>
>   a &= ~0b00001000;
>
>   a &= 0b11110111;

cool danke, weiß jetz was das is, danke

lg andy

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.