Bit in einen Byte setzen

Wie auch beim Bit prüfen stehen auch beim Setzen einzelner Bits verschiedene Methoden zur Verfügung. Erst möchte ich die Inline-Variante aufzeigen. Beim Setzen eines Bits muss lediglich das Byte mit der Bitmaske (hier 0000 0100) „verodert“ werden.

//Bitnummer 2 setzen
int x = 0x9;         // Bitmuster 0000 1001
x = x | 0x4;         // gesetzt weil 0x4 -> 0000 0100

Beim Zurücksetzen (löschen) eines Bits muss die Bitmaske negiert werden um dann mit dem Byte „verundet“ zu werden. Klingt seltsam – ist es aber nicht.

//Bitnummer 2 löschen
int x = 0xd;         // Bitmuster 0000 1101
x = x & (~0x4);      // gelöscht weil ~0x4 -> 1111 1011

Natürlich besteht auch hier die Möglichkeit das Ganze in eine Funktion zu packen. Das Ergebnis einer Schiebe-Operation ist in der Regel ein int. Deshalb auch der Cast in ein BYTE um die Compiler-Warnungen zu unterbinden.

//Bit setzen / löschen
BYTE SetBit(BYTE data, BYTE Bit, BOOL value)
{
  BYTE mask = (BYTE)(0x1 << Bit);
  if(value == TRUE)
    return (BYTE)(data | mask);
  else
    return (BYTE)(data & (~mask));
}

So wird die neue Funktion verwendet

BYTE x = 0x9;               // Bitmuster 0000 1001
x = SetBit(x, 2, TRUE);    // x = 0000 1101
x = SetBit(x, 3, FALSE);   // x = 0000 0101

Bit in einen Byte testen

Manchmal ist es nötig ein Bit in einen Byte oder Word zu prüfen ob gesetzt oder nicht. für diesen Zweck gibt es verschiedene Ansätze die ich nachfolgend aufzeichnen möchte.

eine Variante ist inline den Wert mit Bitoperationen zu prüfen

//Bitnummer 3 testen
int x = 0x9;         // Bitmuster 0000 1001

if((x & 0x8) > 0)    // TRUE weil 0x8 -> 0000 1000

eine weitere Variante ist das erstellen einer WinCC Funktion. Das Ergebnis einer Schiebe-Operation ist in der Regel ein int. Deshalb auch der Cast in ein BYTE um die Compiler-Warnungen zu unterbinden.

BOOL GetBit(BYTE data, BYTE bit)
{
   BYTE pattern = (BYTE)(0x1 << bit);
   if((data & pattern) > 0)
     return TRUE;
   return FALSE;
}

Das gleiche Beispiel wie oben bei Verwendung der Funktion GetBit. So ist das meines Erachtens lesbarer.

//Bitnummer 3 testen
int x = 0x9;         // Bitmuster 0000 1001

if(GetBit(x, 3))    // TRUE weil 0x8 -> 0000 1000

Die Funktion GetBit kann auch für ein WORD oder DWORD abgeändert werden. Zu beachten ist dann dass die Bitnummern nur dann verwendet werden können wenn die Variablen auch SPS-seitig so definiert sind. Sind das hingegen  SPS-seitig nur einzelne Bits muss die Bytereichenfolge beachtet werden.

noch ein Beispiel:

Variable vom Type WORD -> MW10 (SPS-Seitig Ab M10.0 bis M11.7 16 einzelne Bits)
soll das Bit M10.0 getestet werden muss die Bitnummer 8 verwendet werden.