Arduinoを例によく使うビット演算子のまとめ

 Arduinoとかでなるべく処理速度をはやくしたいときにビット(bit)演算をつかうのですが、たまにしか使わないからよく忘れてしまいます。

 

 周知の内容となりすが、個人的によくつかうビット演算子を、Arduinoで使う場合を例にまとめておきます。

 

スポンサーリンク
スポンサーリンク

ビットシフト

 

 まずはビットシフトです。

 

 私の場合、2、4、8、16、32、64あたりの乗算や除算につかったり、通信などでbyteごとに値を取り出すときにつかったりしてます。あとたまにfloat計算を避けたいときに、大きくビットシフトして演算処理を済ました後にもとに戻したりとかしてます。というかそれ以外にあまり使い道知りません。

 

 言語での記述は「>>」、「<<」です。見たままの方向に右か左にずらすだけです。

 

 例えば

01110000>>2  とした場合、
00011100 となります

00001111<<3 とした場合、
01111000 となります

 指示した分だけ右か左にずらすだけです。

 

 右へシフトした場合、ずらしたところは「0」で埋めますが、定義している変数の大きさや負号あり無しによっては少し注意が必要です。ここら辺の動きは言語によって多少異なるようですね。

 

 たとえばbyteの大きさで、

 符号無しの場合、
 11110000>>3 とした場合は、
 00011110 とずれたところは「0」で埋めますが
 
 符号有りの場合、
 11110000>>3 とした場合は、
 11111110 となります。

 マイナスを、右へシフトした場合は「1」で埋めます。ArduinoIDEを使ってる場合は上記のような感じです。

 

 使用例ですが、私の場合、整数の掛け算、割り算を行うとき、2、4、8、16、32、64で掛けたり割ったりする場合や16bit長データの上位、下位データを取り出したりするときに結構使ってます。

 

 あとfloat演算避けたい場合(なるべく処理を早くしたい場合)、なんかにこの考え方使って演算したりしてます。その場合はunion(共用体)使っていますが・・。

>> union(共用体)の使い道

 

AND(論理積)

 

 Arduinoで使う場合、目的のデジタルピンを「LOW」にしたり、ピン状態が「HIGH」なのか「LOW」なのかを調べる場合に使うことが多いです。

 

 論理積は両方ともが「1」の場合にのみ「1」を返します。言語では「&」と記述します。

 

 ですので例えば、5と6bit目のみ「0」にしたい場合、

 11110000
&10011111
------------
10010000

 とすれば、目的のビットのみ「0」にしてそれ以外はそのままです。

 

 使用例。Arduinoで使う場合、例えば13ピンと12ピンを「LOW」にする場合、

digital.write(13,LOW);
digital.write(12,LOW);

 などと記述するかと思います。

 

 ビット演算で行う場合は、

PORTB &= B11001111;

 とポートを直接制御して13ピンと12ピンのみをLOWにします。(ArduinoUNO(ATmega328)の場合は、PORTBにArduinoの8~13pinとICSPpinの一部が割り当てられています)

 

 この記述の方が、複数のピンを同時に処理出来ますし、Arduinoライブラリ使うより処理速度が早いです。

 

 他にピンの状態を調べたりするときにも使います。

 

 例えば

PORTB &= B00100000;

 として結果値を見れば13pinがHIGHかLOWかが分かります。

 

 AND処理は目的のビットを0にするため、マスクなどという場合もあります。

 

スポンサーリンク

OR(論理和)

 

 ANDと同じような使い方になります。こちらは、目的のデジタルピンを「HIGH」にする場合に使ったりしてます。

 

 論理和はどちらかが「1」であれば「1」を返します。言語では「|」と記述します。

 

 例えば5ビットと6ビット目を「1」にしたい場合、

   01000101
or 01100000
--------------
01100101

 といった感じて目的にビットのみ「1」にして、それ以外はそのままです。

 

 Arduinoで13、12ピンを同時にHIGHにしたい場合、

PORTB |= B00110000;

 こんな感じで記述すればHIGHにできます。

 

XOR(排他的論理和

 

 これもちょこちょこ使います。ビットが異なるときに「1」を返します。言語では「^」と記述します。

    00001111
xor 01001000
---------------
01000111

 「1」がたってるところのビットが反転します。

 

 ですのでArduinoなんかでは例えば13pinの出力を反転させたい場合なんかは

PORTB ^= B00100000;

 このように記述します。Lチカなんかはこの記述のみで実現できますね。

 

 私がよくつかうビット演算子はこんなところです。特に処理速度を早くする必要がない場合は、IDEのライブラリ使ったほうが簡単で分かりやすいかと思います・・。

 

コメント