16bitを上位8bit,下位8bitに分ける,2つの8bitを16bitに結合する【C言語お勉強シリーズ】

C言語

題名のまんまですが、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

結合できました(^^)

おしまい。

コメント

タイトルとURLをコピーしました