Forum: Mikrocontroller und Digitale Elektronik Bitoperationen: Bitmaske schreiben


von DraconiX (Gast)


Lesenswert?

Ich würde gerne eine Bitoperation mit einer Bitmaske machen. Ich hab in 
einem 4Byte großen Register an einer Stelle zwei Werte die ich verändern 
möchte, am liebsten natürlich in einer Operation. Ich zeig mal wie ich 
das vorhabe:
1
uint32_t Register = 0;
2
3
// Ich möchte Bitposition z.b. 10 und 11 ändern:
4
5
Register |= (1 << 10); // Schiebt eine 1 an Bit 10
6
Register |= (2 << 10); // Schiebt mir eine 1 an Bit 11
7
Register |= (3 << 10); // Schiebt jeweils eine 1 an Bit 10 und 11)


Nun aber, wenn Bit 10 bereits eine 1 enthält würde...
1
Register |= (2 << 10);


... ja nun eine 1 an Pos 11 schieben, aber dies ist ja nicht gewollt.

Wie könnte ich dies nun umgehen ohne jedesmal vorher "händisch" Bit 10 
und Bit 11 zu löschen um sie dann wieder zu beschreiben?! Gibts da einen 
Trick in C?

Vielen Dank euch!

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


Lesenswert?

DraconiX schrieb:
> am liebsten natürlich in einer Operation.
Ich denke, dir ist klar, dass das nicht geht. Bestenfalls "in einer 
Programmzeile". Daraus werden dann je nach Prozessor oder Compiler viele 
Operationen...

> ... ja nun eine 1 an Pos 11 schieben, aber dies ist ja nicht gewollt.
>  Wie könnte ich dies nun umgehen ohne jedesmal vorher "händisch" Bit 10
> und Bit 11 zu löschen um sie dann wieder zu beschreiben?!
Gar nicht. Das ist ein Read-Modify-Write-Zugriff, weil ja die ganzen 
anderen Bits nicht verändert werden sollen.

> Gibts da einen Trick in C?
Jetzt nochmal die Frage: Wofür? Dafür, dass alles in 1 Programmzeile 
steht?

von Falk B. (falk)


Lesenswert?

@ DraconiX (Gast)

>Ich würde gerne eine Bitoperation mit einer Bitmaske machen. Ich hab in
>einem 4Byte großen Register

Variable. Register hast du nur in Assembler.

>Register |= (1 << 10); // Schiebt eine 1 an Bit 10

Ja.

>Register |= (2 << 10); // Schiebt mir eine 1 an Bit 11

ja, aber schlechte Schreibweise. Besser so

Register |= (1 << 11); // Schiebt mir eine 1 an Bit 11

>Register |= (3 << 10); // Schiebt jeweils eine 1 an Bit 10 und 11)

>Nun aber, wenn Bit 10 bereits eine 1 enthält würde...
>Register |= (2 << 10);

>... ja nun eine 1 an Pos 11 schieben, aber dies ist ja nicht gewollt.

Komische Logik. Du schreibst eine 1 an Bit 11 und "beschwerst dich" über 
eine möglicherweise vorhandene 1 an Bit 10?

>Wie könnte ich dies nun umgehen ohne jedesmal vorher "händisch" Bit 10
>und Bit 11 zu löschen um sie dann wieder zu beschreiben?!

Löschen und schreiben.

> Gibts da einen Trick in C?

Nicht wirklich.

Register &= ~(3 << 10);   // Bit 10+11 löschen

Siehe Bitmanipulation.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

DraconiX schrieb:
> Wie könnte ich dies nun umgehen ohne jedesmal vorher "händisch" Bit 10
> und Bit 11 zu löschen um sie dann wieder zu beschreiben?! Gibts da einen
> Trick in C?

Erstmal verstehe ich nicht, warum Du Bits erst löschen und dann wieder 
setzen willst ... und das in einer Operation?!? Das klingt ziemlich 
wirr.

Außerdem redest Du dauernd was von "Schieben". Deine Zeilen "schieben" 
gar nichts.

(1 << 10) ist bereits zur Compile-Zeit nichts anderes als 0b10000000000. 
Da wird gar nichts geschoben.

Bits in Register setzen:

Register |= Bitmaske;

Bits in Register löschen:

Register &= ~Bitmaske;

Register auf einen Wert setzen:

Register = Bitmaske;

Siehe auch Bitmanipulation

von Rene K. (xdraconix)


Lesenswert?

Lothar M. schrieb:
> Ich denke, dir ist klar, dass das nicht geht. Bestenfalls "in einer
> Programmzeile". Daraus werden dann je nach Prozessor oder Compiler viele
> Operationen...

Ja, das ist mir bewusst.

Um es mal zu verdeutlichen: ich möchte auf einem STM32 im GPIO_CRL/CRH 
Register den Mode ändern welcher aus zwei Bits besteht 
(00-Input,01-10Mhz,10-2Mhz,11-50Mhz).

Da dachte ich mir es wäre halt eine einfachere Schreibweise. Um ein 
vorheriges löschen der Bits werde ich wohl nicht umher kommen.

Aber vielen Dank eurer Hilfe.

Beitrag #5305159 wurde von einem Moderator gelöscht.
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.