題名のまんまですが、16bitを上位8bit、下位8bitに分ける方法と、逆に、2つの8bitを16bitに結合する方法についてのメモです(^^)
用途
- シリアル通信(UART)の送受信単位は1文字=1byte(8bit)なので、マイコンで16bitで定義した値を上位8bit、下位8bitに分けて送信したい。(PC側で16bitに結合して表示)
- 1byte(8bit)で受信したデータをマイコンで16bitに結合して、値を得たい。
16bitを上位8bit、下位8bitにわける
やっていることは以下です。
- 上位8bitを抽出 : 右に8bitシフト(下位8bitにシフト)
- 下位8bitを抽出 : 0x00FFと”&”(アンド)をとる
// 2byte(16bit)を上位8bit,下位8bitにわける
unsigned short a,bH,bL // 2byte(16bit)で宣言
// bH : aの上位8bitを入れる
// bL : aの下位8bitを入れる
a = 0x4F1A; // 適当な値(2byte)
// aの上位8bitをbHに入れる
bH = a >> 8; // 右に8bitシフト(下位8bitにシフト)
// bH = 0x004F
// aの下位8bitをbLにいれる
bL = a & 0x00FF; // 0x00FFと&をとる
// bL = 0x001A
上位8bitの抽出
a = 0x4F1Aのように、適当な値を16進数で定義しました。
2進数で表現すると、a = 0b 0100 1111 0001 1010 (0bは2進数の意味)
aの上位8bitは右に8bitビットシフトすることで得ます。
”»”は右にビットシフトする演算子です。
a = 0b 0100 1111 0001 1010
↓↓ bH = a » 8 ↓↓
bH = 0b 0000 0000 0100 1111 = 0x004F ( = 0x4F ) ※0は省略可能
シフトして空いたところには”0″が入ります。
8bit右にシフト(下位8bitにシフト)するのは、小さい型(16bitの数値を8bitのレジスタに入れるなど)に入れると、上位8bitは捨てられ、下位8bitが残るからです。
これで、aの上位8bitが抽出できました。
下位8bitの抽出
下位については、上記の通り、小さな型に入れる場合は自動的に下位bitだけ残るので、何もする必要はありませんが、そのままの型(ここでは16bitのまま)だと、上位bitの値(4F)が残ったままになってしまうので、これをなんとかします。
具体的には上位8bitを全部0にします。
それには、0x 00FFと&(アンド)をとります。
アンドを取るということは、1と1以外は0になります。すると、上位8bitはすべて0になります。
a = 0x4F1A = 0b 0100 1111 0001 1010
0x00FF = 0b 0000 0000 1111 1111
↓↓ bL = a & 0x00FF ↓↓
bL = 0b 0000 0000 0001 1010 = 0x001A ( = 0x1A ) ※0は省略可能
よって、aの下位8bitが抽出できました。
2つの8bitを16bitに結合する
今度は反対に、2つの8bitを16bitに結合します。
- 上位8bitに相当する部分 : 左に8bitシフト(上位8bitにシフト)
- “|”(OR)をとる
unsigned short a,bH,bL
bH = 0x4F;
bL = 0x1A;
a = (bH << 8) | bL; //bHを8bit左にシフトして、bLとORをとる
// a = 0x4F1A
例のごとく、また2進数で考えます。
bH = 0x4F = 0b 0000 0000 0100 1111
↓↓ bH « 8 ↓↓
= 0b 0100 1111 0000 0000 = 0x4F00
これもシフトして空いたところには0が入ります。
ORをとると、0と0なら0、1と1なら1、0と1なら1となります。
bH « 8 = 0b 0100 1111 0000 0000
bL = 0x1A = 0b 0000 0000 0001 1010
↓↓ a = (bH « 8) | bL ↓↓
a = 0b 0100 1111 0001 1010 = 0x4F1A
結合できました(^^)
おしまい。