ビットシフトのはなし
ビットシフトとは
[Bit Shift ]で、デジタルデーターの1ビットずつを左右に動かせる、便利な命令です。
例えば 2進法では 10進法の4 は、00000100b と表します。 bは2進法表記のこと、16進表記では
0x04 とか書きます。これを例えば A という8ビットの変数に入れます。
A = 00000100b
ですね。
これをビットシフト演算子で右に1つシフトさせると
A = A >> 1 ;
と書きます。; はc言語の区切り記号です。
そうするとどうなるかというと
A = 00000010b = 0x02 = 2
になります。
1が右に1つズレていますね。
同様に
A = 00000100b ;
A = A << 1 ;
と書くと
A = 00001000b = 0x08 = 8
となります。
つまり、
右シフト >> は2分の1にすること
左シフト << は2倍にすることになります。
2進法だから当たり前ですが...
ハード的には
なにが便利かというと、例えば右図のように1つの8ビットポートに繋がれた LEDをレベルに応じて点灯させる時など
(この図では、Portが Low で点灯する回路ですから、光らせたいビットを0にします。)
switch(level){
case 0 :
PortD = 11111111b; //レベル0
break;
case 1:
PortD = 11111110b; //レベル1
break;
....
....
などとやるよりも
unsigned char segdata ;
segdata = ( 0xff << level );
PortD = segdata ;
で、出来てしまいます。
シフトして右からは 0が入ってくるのでこのようなことが出来ます。
ソフト的には
しかしながら、時々コンパイラによったり、CPUによったりして、時々困ったことが起きます。
今回も PIC で起こったことは...
LEDを光らせることで使ってましたが、以前はLowをセグメント出力して光らせていたのですが、今回仕様が変わって間にインバーターバッファが入ったので、光らせるビットを 1 にしなければなりません。
以前のソフトは
unsigned int BitData ;
unsigned char SegData ;
BitData =( 0xff00 << level );
SegData = BitData >> 8 ;
と int の上位8ビットを使ってポート出力時に 8ビットに変換していました。
ビット反転でも対応出来るし、初期値を 0xFF7F とすれば1個だけ点灯もできるし..と思って作ってました。
それで今回は
unsigned int BitData ;
unsigned char SegData ;
BitData =( 0x00ff << level );
SegData = BitData >> 8 ;
と単純にやっただけなのですが、結果は SegData はいつも 0x00 のまま。
level = 2 の時には
BitData = 0x00fc と下側8ビットの中でしかシフトしていません。
おかしいなーと思って、
unsigned int BitData ;
unsigned char SegData ;
BitData =( 0xff00 << level );
SegData = ~(BitData >> 8) ; //~ を使って単純にビットを反転
とりあえずこれでOKにしてしまいました。
しかしちょっと納得がいかないので追求しました。
unsigned int BitData ;
unsigned char SegData ;
BitData =( 0x0fff << Level ); //8ビット境界を越えて動くか実験
SegData = BitData >> 8 ;
level = 2 のとき
SegData = 00111111b といくではないですか?
どうやらコンパイラが初期値で変になっているようなので、
unsigned int BitData ;
unsigned char SegData ;
BitData = 0x0fff ; //初期値を入れてやる
BitData = BitData >> 4 ; //希望の値 0x00ffにする
BitData =( BitData << Level );
SegData = BitData >> 8 ;
これで動きました!
なんか追求するといろんな不具合がありそうで、チェックしないとけっこう大変ですね
こんなことでも、コンパイラにうまく思いを伝えないとやっぱ動かないんですね〜
| 固定リンク
「DIGITAL」カテゴリの記事
- TTL レベルのはなし ふたたび(2022.02.13)
- 2022 新年あけましておめでとうございます。(2022.01.04)
- 12Bit DAコンバーターのはなし(2016.08.12)
- D ラッチとD フリップフロップのはなし(2014.10.30)
- XPにさよなら(2014.08.12)
コメント