はじめに
こんちゃす!
今回はお勉強回です。
bit演算子ってやつです。マイコンを使用した組み込み開発を行っているとレジスタ操作などでbit単位で演算することは必須ですよね。
私くろべこはよく演算子の機能を忘れるので、その度にグーグル先生に聞いて調べていることが多々あります。
ので、今回はよく使用するbit演算子のまとめと使い道を紹介という名の備忘録記事になります。
bit演算子まとめ
bit演算子一覧
機能 | 演算子 | 使用例 |
OR | | | 指定bitのセット |
AND | & | 指定bitの取り出し, NOTと併用した指定bitのクリア |
XOR | ^ | bit反転 |
NOT | ~ | bit反転, bitクリア |
ビットシフト(右) | >> | ビットシフト |
ビットシフト(左) | << | ビットシフト |
よくある表ですね。+αとして、使用例をつけてみました。次の項で詳細の説明をしますね。
今回は教材用のデモコードとして以下のコードを使用しながら進めていきたいと思います。
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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
#include<avr/io.h> #include<avr/wdt.h> #include <util/delay.h> void setup() { DDRB = 0b00011111;//PORTB設定 PORTB = 0b00011101;//PORTB出力設定 //ビット演算デモコード① /* _delay_ms(2000); PORTB |= 0b00000010 ;//ORtest _delay_ms(2000); PORTB &= ~0b00000011;//ANDtest _delay_ms(2000); PORTB ^= 0b00000011;//XORtest _delay_ms(2000); for(int i=1;i<5;i++){//右ビットシフトテスト PORTB >>= 1; _delay_ms(500); } _delay_ms(2000); for(int i=1;i<5;i++){//左ビットシフトテスト PORTB <<= 1; _delay_ms(500); } _delay_ms(2000); PORTB = ~PORTB; */ //ビット演算デモコード② /* //4bitまとめて位置を指定してクリア _delay_ms(2000); PORTB &= ~(0b00001111<<2); //4bitまとめて位置を指定してセット _delay_ms(2000); PORTB |= (0b00001111<<1); */ } void loop() { wdt_reset(); //pin状態の読み取り(PCINT4にSWをつけていると仮定) DDRB = 0b00000001;//PORTB設定 PORTB = 0b00010000;//PORTB出力設定(PIN4を入力プルアップ) bool state;//ボタンの状態(1:ON,0:OFF) state = (~PINB>>4) & 1; //ボタンが押されたらPIN0をHIGH switch(state){ case 0: PORTB &= ~0b00000001; break; case 1: PORTB |= 0b00000001; break; } } |
デモの回路はPB0~PB4にLEDをつけてみてください。
bit演算デモコード①
デモコードなのですが、ATtiny13のPORTBを使用して実際にbit演算の確認を行っていこうと思います。使用するbitはPB0~PB4です。初期状態はPB1以外はHIGHをしています。
1.初期状態
PORTB = 0b00011101;
2.OR ( | ):演算式の左辺と右辺のどちらかが1だったらbitをセットする
1bit目指定でセットします。
1 |
PORTB |= 0b00000010; |
3.AND( & ):演算式の左辺と右辺の両方が1だった場合bitをセットする
NOTと組み合わせて0bit, 1bitをクリアします。
1 |
PORTB &= ~0b00000011; |
4.XOR( ^ ):演算式の左辺と右辺で値異なる場合bitをセットする
0bit, 1bitを反転します。
1 |
PORTB ^= 0b00000011; |
5.bit右シフト(>>):右辺の値分左辺のビットを右にシフトする
1bitずつ右にシフトします(計四回)。
1 |
PORTB >>= 1; |
6.bit左シフト(<<):右辺の値分のビットを左にシフトする
1bitずつ左にシフトします(計四回)
1 |
PORTB <<= 1; |
7.NOT( ~ ):論理を反転します
PORTBの論理を反転します。
1 |
PORTB = ~PORTB; |
bit演算デモコード②
ここではデモコードで紹介した演算子の組み合わせを紹介していきます。初期状態はデモコード①と同じです。デモコード①をコメントアウトしてご使用ください。
1.まとめてのbitクリア
4bit分を2bit左にbitシフトさせて、bit2~bit5をクリアします。
1 |
PORTB &= ~(0b00001111<<2); |
2.まとめてbitセット
4bit分を1bit左にbitシフトさせて、bit1~bit4をセットします。
1 |
PORTB |= (0b00001111<<1); |
おまけ
最後にANDを使用したbit状態の抽出を紹介して終わります。
デモコード①と②はコメントアウトしてください。
また、回路はPB0にLEDを取り付けて、PB4とGNDとの間にスイッチのみを入れてください。(LEDはつながないでください)
何をやるのかというとPB4をbit入力ピンとしてます。そしてANDを使用し、PB4のbit状態を抽出して、そのbit状態によってPB0のLEDを光らせていきます。
1 |
state = (~PINB>>4) & 1; |
PB4は内部プルアップさせているのでスイッチが押されていないときは1です。
演算式ではいったんPINBのbit状態を反転させて4bit右にシフトさせます。これでPB4のbit状態がPB0に移動します。そして1とANDで比較します。もしもスイッチが押されている場合は1がstate変数にセットされて、押されていない場合は0がセットされます。
LEDの点灯制御に関してはSWITCH関数で分岐させています。
以下の動画に内容をまとめておりますのでご覧いただければと思います。
おわりに
今回は備忘録としてbit演算子のまとめを行いました。
これで機能を忘れたときも自分のブログを見に来ればよくなりました。
というくらい私の為だけの記事だったかもしれません。でも、使用方法とかはよく使うものなので覚えておいて損はないかと思います。
以上です!では!
コメント