Arduinoでのビットマスク

ビットマスクは、1バイト内のデータの特定のビットにアクセスするのに使われます。


AUTHOR: Arduino、LAST REVISION: 2022/11/23 23:29


ビットマスクは、1バイト内のデータの特定のビットにアクセスするのに使われます。これは繰り返し方法として有用なことがあります。例えば、1バイトのデータをひとつのピンからシリアルに送信する場合です。この例では、送信するバイト内の各ビットに応じて、ピンの状態をHIGHとLOWに変更する必要があります。これは、ビット単位の演算子とビットマスクを用いて実現されます。

ビット単位の演算子は、ビットレベルで影響を及ぼす論理関数です。標準的なビット単位の演算子には、AND(&)とOR(|)、左シフト(«)、右シフト(»)があります。

AND演算子(&)は、双方の入力の値が1のとき、各ビットの位置が1となります。例えば、

1
2
3
4
5
x:      10001101
    
    y:  01010111

x & y:  00000101

包含的論理和としても知られるOR演算子(|)は、どちらかの入力の値が1のとき、各ビットの位置が1となります。例えば、

1
2
3
4
5
x:      10001101

    y:  01010111

x | y:  11011111

左シフト演算子(«)は、指定した数だけ元の値を左にシフトします。例えば、

1
2
3
4
5
        y = 1010

        x = y << 1

yields: x = 10100

バイト内の全てのビットが左に一つシフトし、一番左のビットはなくなります。

右シフト演算子(»)は、指定した数だけ元の値を右にシフトすること以外は、左シフト演算子と同じように動作します。

1
2
3
4
5
        y = 1010

        x = y >> 1

yields: x = 0101

バイト内の全てのビットが右に一つシフトし、一番右のビットはなくなります。

実用的な例として、170(2進数で10101010)を考えてみましょう。この値を7番ピンにパルスとして出力するコードは、以下のようになります。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
byte transmit = 7; //define our transmit pin
byte data = 170; //value to transmit, binary 10101010
byte mask = 1; //our bitmask
byte bitDelay = 100;

void setup()
{

   pinMode(transmit,OUTPUT);
}

void loop()
{

  for (mask = 00000001; mask>0; mask <<= 1) { //iterate through bit mask

    if (data & mask){ // if bitwise AND resolves to true

      digitalWrite(transmit,HIGH); // send 1

    }

    else{ //if bitwise and resolves to false

      digitalWrite(transmit,LOW); // send 0

    }

    delayMicroseconds(bitDelay); //delay

  }
}

ここでは、ビットマスクの値をループ内で左にシフトしていくことで、forループで繰り返します。この例では<==演算子を使っていますが、«と全く同じで、文を簡潔にします。

1
2
3
4
5
6
  00000001
& 10101010

  ________

  00000000

最初のループで出力ピンは0となります。2回目のループでは、mask=00000010なので、演算は以下のようになります。

1
2
3
4
5
6
  00000010
& 10101010

  ________

  00000010

その結果、出力ピンは1になります。1が8ビットの終わりから左にシフトされmask=0となるまで、ループはマスクの各ビットを繰り返します。その結果8ビットすべてが送信され、ループを抜けます。

オリジナルのページ

https://docs.arduino.cc/learn/programming/bit-mask

最終更新日

January 28, 2024

inserted by FC2 system