Arduinoリファレンス

Arduinoリファレンスの日本語訳のページです
garretlab
ビット単位のAND演算子/ビット単位のOR演算子/ビット単位の排他OR演算子

名称

ビット単位のAND演算子/ビット単位のOR演算子/ビット単位の排他OR演算子

説明

ビット単位の演算子は、変数や数値のビット単位の計算を行う。プログラムに共通する幅広い問題を解くことに役立つ。以下は、ビット単位の演算の学習に役立つチュートリアルからの抜粋である。

&(ビット単位のAND演算子)

C++言語におけるビット単位のAND演算子は&であり、整数型を持つ二つの式に対して適用される。ビット単位のAND演算子は、式の個々のビットごとに演算が行われる。この規則に従うと、双方のビットが1のとき結果が1となり、そうでなければ0である。例を以下に示す。

0 0 1 1 オペランド1
0 1 0 1 オペランド2
------
0 0 0 1 (オペランド1 & オペランド2) - 計算結果

Arduinoでは、int型は16ビットの大きさなので、二つのint型の式に&を適用すると、16個のAND演算が同時に起こる。

    int a =  92;    // 2進表記: 0000000001011100
    int b = 101;    // 2進表記: 0000000001100101
    int c = a & b;  // 結果:    0000000001000100, 68(10進表記)

aとbのそれぞれの16ビットに対して、AND演算子が適用され、16個の演算の結果がcに格納される。上記の例の場合、2進数で010000100、10進数で68となる。

ビット単位のAND演算子のよくある使い方は、整数値から特定のビットを選択することであり、マスキングと呼ばれる。

|(ビット単位のOR演算子)

C++言語におけるビット単位のOR演算子は|である。ビット単位の&演算子同様、ビット単位のOR演算子は、整数型を持つ二つの式の個々のビットごとに演算(もちろん異なる演算)が行われる。どちらかのビットが1のとき結果が1となり、そうでなければ0である。例を以下に示す。

0 0 1 1 オペランド1
0 1 0 1 オペランド2
------
0 1 1 1 (オペランド1 | オペランド2) - 計算結果

C++コードの一部を使って、ビット単位のOR演算子の例を示す。

    int a =  92;    // 2進表記: 0000000001011100
    int b = 101;    // 2進表記: 0000000001100101
    int c = a | b;  // 結果:    0000000001111101, 125(10進表記)

使用例(Arduino Uno)

ビット単位のANDやOR演算子の共通の役割は、プログラマがRead-Modify-Writeと呼ぶポートに対する操作である。マイクロコントローラ上は、ポートは、ピンの状態を表す8ビットの数値である。ポートへの書き込みにより、全てのピンを一度に制御することができる。

PORTDは、デジタルピンの0、1、2、3、4、5、6、7番ピンの出力状態を表す、事前定義された定数である。その中のビットに1が立っていれば、そのピンはHIGHである(各ピンはpinMode()関数によって、事前に出力状態としておく必要がある)。PORTD=B00110001と記述すると、デジタルピン0、4、5番ピンをHIGHにしたことになる。ここでの一つのわずかな問題はArduinoのシリアル通信によって利用される0番ピンと1番ピンとの状態を変えてしまうことで、シリアル通信に影響を及ぼす可能性があることである。

プログラムでのアルゴリズムは以下の通り。

(訳者註)このプログラムは、6ビットであらわすことの整数(0から63)を、2番ピンから7番ピンに2進表示する。2番ピンから7番ピンにLEDを接続すれば、1になっているピンが点灯する。たとえば、3のときは、2番ピンと3番ピンとが点灯することになる。

  • PORTDの値を取得して、ビット単位のAND演算子を使って制御したいピンだけを0にする。
  • ビット単位のOR演算子を使って、制御したいピンに新しい値を設定し、新しいPORTDの値とする。
int i;     // カウンタ用変数
int j;

void setup(){
  DDRD = DDRD | B11111100; // 2番ピンから7番ピンの入出力ビットを設定する。0番ピンと1番ピンは変更しない。(xx | 00 == xx)
  // 2番ピンから7番ピンに対してpinMode(pin, OUTPUT)とするのと同じ。
  Serial.begin(9600);
}

void loop(){
  for (i=0; i<64; i++){
    PORTD = PORTD & B00000011;  // 2番ピンから7番ピンをLOWにする。0番ピンと1番ピンは変更しない。(xx & 11 == xx)
    j = (i << 2);               // 変数の値を2番ピンから7番ピンにマッピングする。 - 0番ピンと1番ピンは変更しない。
    PORTD = PORTD | j;          // LEDピンの情報を更新する。
    Serial.println(PORTD, BIN); // デバグ用にシリアルポートにPORTDの値を表示する。
    delay(100);
  }
}

^ (ビット単位の排他OR演算子)

ビット単位の排他OR演算子という耳慣れない演算子がC++にはある。ビット単位の排他OR演算子は、^で表す。この演算子は、双方のオペランドが1のとき0になることを除いて、ビット単位のOR演算子と似ている。

0 0 1 1 オペランド1
0 1 0 1 オペランド2
------
0 1 1 0 (オペランド1 ^ オペランド2) - 計算結果

ビット単位の排他OR演算子では、それぞれのビットが異なるときに1になり、同じときには0になると説明することもできる。

ビット単位の排他OR演算子の例を示す。

    int x = 12;     // 2進表記: 1100
    int y = 10;     // 2進表記: 1010
    int z = x ^ y;  // 結果: 0110, 6(10進表記)

使用例

ビット単位の排他OR演算子は、整数式の特定のビットを反転(0を1に、1を0にする)するときによく使われる。ビット単位の排他OR演算子を使うと、マスクビットが1のときは反転し、0のときはそのままである。以下の例は、デジタルピンの5番を点滅させる。

// Blink_Pin_5
// demo for Exclusive OR
void setup(){
  DDRD = DDRD | B00100000; // set digital pin five as OUTPUT 
  Serial.begin(9600);
}

void loop(){
  PORTD = PORTD ^ B00100000;  // invert bit 5 (digital pin 5), leave others untouched
  delay(100);
}

バージョン

Arduino 1.8.4



メニューを表示するためにJavaScriptを有効にしてください。

inserted by FC2 system