Forum: Mikrocontroller und Digitale Elektronik Hilfe bei bitweiser Manipulation einer Variable


von Hans (Gast)


Lesenswert?

Hallo Leute!

Ich brauche mal eure Hilfe. Ich habe eine 16Bit breite Variable, welche 
ein Reihe vom Flags beeinhaltet. Jetzt möchte ich nur einzelne Bits 
dieser Variable ändern, indem ich an eine Funktion einen neuen Wert 
schicke.

Beispiel (pseudo-Code):
1
flags: 0010 1000 1101 0010
Die letzten vier Bits sind jetzt die Stellen, die ich manipulieren will. 
Ziel ist es, per Funktion
1
void change_bits( 0x0004 | 0x0001 );
eben nur diese letzten vier Bits auf den neuen Wert zu setzen, sodass am 
Ende
1
flags: 0010 1000 1101 0101
herauskommt.

Aber wie verknüpfe ich das? So geht es zumindest schonmal nicht:
1
void change_bits( uint16_t new_flags )
2
{
3
  flags &= (new_flags & 0x000F);
4
}

Da ist dann alles weg, was auch klar ist. Aber ich komme nicht auf die 
richtige Verknüpfung.

Kann einer helfen?
[/c]

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Um die unteren vier Bits auf einen komplett neuen Wert zu setzen, musst 
Du in zwei Schritten vorgehen:

Erst die Bits löschen

  a &= 0xFFF0;

dann die Bits auf den neuen Wert setzen:

  a |= neue_bits;

Um sicherzustellen, daß die "neuen bits" nur die unteren vier Bits 
verändern, kannst Du diese noch maskieren:

  a |= (neue_bits & 0xF);

von Achim M. (minifloat)


Lesenswert?

Hans schrieb:
> Jetzt möchte ich nur einzelne Bits
> dieser Variable ändern

Erst mit dem Negat der zu beeinflussenden Bits ver-&-en, damit die bits 
Fallen, denen du einen neuen Wert zu weisen willst.
Zweitens dann die entsprechenden Bits drauf-Odern.

Mit einer Funktion, die eine einzige Variable nimmt, geht das nicht, du 
musst zusätzlich eine Maske mitliefern. Woher soll die Funktion sonst 
wissen, dass eine 0 aktiv gesetzt werden soll oder nur so belassen 
werden soll, wie sie ist.

Alternativ kannst du auch zwei Masken übergeben: zu löschende und zu 
setzende Bits.

mfg mf

von Klaus (Gast)


Lesenswert?

flags += 3;

MfG Klaus

von Hans (Gast)


Lesenswert?

Klaus schrieb:
> flags += 3;

LOL!!!!! Danke!

Mini Float schrieb:
> Erst mit dem Negat der zu beeinflussenden Bits ver-&-en, damit die bits
> Fallen, denen du einen neuen Wert zu weisen willst.

OK, also in einem geht das nicht. Vielen Dank!

von (prx) A. K. (prx)


Lesenswert?

Rufus Τ. Firefly schrieb:
>   a &= 0xFFF0;

Stilistisch besser:
    a &= ~0xF;

von Hans (Gast)


Lesenswert?

Ich habe jetzt
1
flags &= ~BITMASKE;
2
flags |= neuer_wert;

Passt, danke! Dachte nur, es gibt vielleicht eine super ver-und/oderung, 
welche es direkt bewerkstelligt.

Aber alles OK. Danke!

von Achim M. (minifloat)


Lesenswert?

Hans schrieb:
> es gibt vielleicht eine super ver-und/oderung,
> welche es direkt bewerkstelligt

Nein, die kann es aus mathematischer Sicht nicht geben. Es gibt drei 
Zustände pro Binärem Digit der Eingangsvariable, die die Operation, die 
du ausführen willst, vollständig notieren:
1. Bit auf 0 setzen
2. Bit auf 1 setzen
3. Bit lassen wie es ist
Das ist trinär , lässt sich also nicht in einer Binärzahl gleicher 
Stellenanzahl ausdrücken.

Weil eh 2 Bits verwendet werden, bleibt noch eine Möglichkeit übrig:
4. Bei einem JK-Flipflop gibt es noch Toggeln

mfg mf

von Volkmar D. (volkmar)


Lesenswert?

Hans schrieb:
> Ich habe jetztflags &= ~BITMASKE;
> flags |= neuer_wert;
>
> Passt, danke! Dachte nur, es gibt vielleicht eine super ver-und/oderung,
> welche es direkt bewerkstelligt.

Mini Float schrieb:
> Nein, die kann es aus mathematischer Sicht nicht geben.

Nichtsdestotroz kann man dies natürlich auch in eine Anweisung setzen:
1
flags = (flags & ~BITMASKE) | neuer_wert;

von Achim M. (minifloat)


Lesenswert?

Volkmar Dierkes schrieb:
> Nichtsdestotroz kann man dies natürlich auch in eine Anweisung
> setzen:flags = (flags & ~BITMASKE) | neuer_wert;

Da stimm ich dir voll zu! Schöner, kompakter, gut lesbarer Code ist 
durch nichts zu ersetzen :)
Aber ohne zusätzliche Bitmaske, die definiert, wo überhaupt was getan 
werden soll, geht es halt nicht. mf

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.