ich suche nach einer komfortablen Möglichkeit ein Byte folgendermaßen zu ändern.
Ausgangsbasis:
11101101
Die vier Bits in der Mitte sollen folgende "Werte" annehmen:
0001
Ergebnis:
11000101
Ich möchte praktisch erreichen, dass mehreren Bits gleichzeitig Werte annehmen, unabhängig von deren Ursprungszustand.
Ich kann mir vorstellen, dass man hierfür eine "Bitmaske" verwenden könnte, weiss aber nicht, wie man in Anbetracht der Tatsache, dass ich die neuen Werte unabhängig von den Ursprungswerten geschrieben werden sollen, damit umgeht.
Hallo,
zuerst mit AND ausmaskieren, z.B. 11111111 AND 11000011 = 11000011, setzt also die gewünschten Bits auf Null. Dann mit OR die gewünschten Bits wieder einschalten: 11000011 OR 11011011 = 11011011.
Bei AND wird das Bit im Ergebnis nur dann 1, wenn beide Bits in den Operanden auch 1 waren, sonst wird es null:
A B Q
0 0 0
0 1 0
1 0 0
1 1 1 A AND B ergibt Q
Bei Or wird das Bit im Ergebnis 1, wenn eines der beiden Eingangsbits 1 war:
schreiben. Ich weiß nicht, ob das die Anforderung "einzelner Befehl" erfüllt. Mit einer einzigen Anweisung geht es nicht. Du musst die Bits erst ausmaskieren, ehe Du sie neu setzen kannst.
Gruß,
Ralf
[Edit:] Oben nur zur Verdeutlichung. in C muss es natürlich heißen Q = A & B | C;
In Datenblättern sieht man schonmal Bits mit 3 Zuständen ( 0 1 X ) Das gibts aber in C nicht direkt.
Auch Operatoren mit 3 Eingängen sind eher "ungewöhnlich", und leichter verständlich, wenn man sie direkt als Funktion definiert:
mask hat hier eine andere Bedeutung als B in Ralf Schachmanns Beispiel
Ausserdem werden hier -sicherheitshalber- noch evtl. überzählige Bits in input ausgeblendet.
Ob du einen Funktionsaufruf oder einen Ausdruck mit 2 Operatoren bevorzugst, ist eigentlich Geschmackssache.
Die Funktion kannst du auch als #define oder inline definieren, so dass im Endeffekt das Gleiche kompiliert wird.
Schon klar, Ralf,
was ich meinte war nur: in C ist ein Bit entweder gesetzt oder nicht, für etwas drittes ( unverändert lassen ) muss man 2 Werte nehmen, in diesem Fall eben die zu setzenden Bits und eine Maske.
Auf die Bitmaske ist Chris ja schon von selbst gekommen, und deine Beiträge sind vollkommen richtig.
Die Syntax mit sowas wie
Q &=~ M;
ist zu Beginn etwas abschreckend, daher mein Zusatztip, evtl. eine Funktion zu definieren.
Schachmann:
Hallo,
zuerst mit AND ausmaskieren, z.B. 11111111 AND 11000011 = 11000011, setzt also die gewünschten Bits auf Null. Dann mit OR die gewünschten Bits wieder einschalten: 11000011 OR 11011011 = 11011011.
Kann es sein, dass bei OR folgendes Byte falsch ist: 11011011
Müsste es nicht 00011000 heissen?
Hier mein Code, der mich auf diese Vermutung brachte:
// Dieser Sketch soll ein Byte mit dem Wert 11101101 in 11000101 ändern. Es werden die mittleren vier Bits unabhängig von Ihrem Ausgangszustand geändert.
byte buffer = 0b11101101;
byte nullungsmaske = 0b11000011;
byte bitsetzer = 0b00000100;
void setup()
{
Serial.begin(9600);
delay(1000);
buffer=buffer&nullungsmaske;
Serial.print("Nach UND-Operator (Maske): ");
Serial.println(buffer,BIN);
delay(1000);
buffer=buffer|bitsetzer;
Serial.print("Nach ODER-Operator: ");
Serial.println(buffer,BIN);
}
void loop()
{
}
Ja. Er hat wahrscheinlich angenommen, dass die äußeren Bits immer 1 sind (so wie in deinem Beispiel ganz am Anfang). In dem Fall wäre es egal. Aber wenn sie auch den Wert 0 annehmen sollen, dann müssen sie in der Maske auch 0 sein.
Wenn die Maske bestimmen soll, welche Bits von wo kommen, wird meist der eine Eingang mit der Maske, der andere mit der invertierten Maske maskiert (UND) und das Ergebnis zusammengeODERt.