汎用的なビットフィールドを扱う(1ビット)
組み込み用途でプログラムをしていると、
IO.PDR1.BIT.B0 = 1;
みたいな感じで、ビットフィールドの操作をよくする。
(char 型の IO.PDR1 の 0 ビット目に 1 をセットする)
ビットフィールドはポインタのように付け替えることが出来ないので、
0系の出力 … IO.PDR1.BIT.B0
1系の出力 … IO.PDR1.BIT.B1
みたいに、複数の系統を同じロジック内で制御する場合に、
以下のような工夫が必要となる。
if (sys == 0) IO.PDR1.BIT.B0 = 1; else IO.PDR1.BIT.B1 = 1;
それだと管理が煩わしいので、
汎用的に扱える関数群を書いてみた。
とりあえず、最も用途の多い1ビット切り替え用になっている。
以下のように使う。
BitSw8 sys_out[3]; initBitSw(sys_out[0], &IO.PDR1, 0); // IO.PDR1.BIT.B0 initBitSw(sys_out[1], &IO.PDR1, 1); // IO.PDR1.BIT.B1 initBitSw(sys_out[2], &IO.PDR1, 2); // IO.PDR1.BIT.B2 setBitSw(sys_out[0], ON); // IO.PDR1.BIT.B0 = 1; setBitSw(sys_out[1], OFF); // IO.PDR1.BIT.B1 = 0; setBitSw(sys_out[2], ON); // IO.PDR1.BIT.B2 = 1; getBitSw(sys_out[0]); // 1 getBitSw(sys_out[1]); // 0 getBitSw(sys_out[2]); // 1 printf("0x%x", IO.PDR1); // 0x05 => 0000 0101
関数呼出しのオーバーヘッドを防ぐためにマクロ関数で定義してある。
/* * Bit Switch: 汎用的なビットフィールドを扱う関数群 * ただし、1ビットの on / off のみを扱う */ #define ON 1 #define OFF 0 // Bit Switch (8bits) typedef struct bitsw8 { unsigned char *adr; unsigned char msk; } BitSw8; // Bit Switch (16bits) typedef struct bitsw16 { unsigned short *adr; unsigned short msk; } BitSw16; // Bit Switch (32bits) typedef struct bitsw32 { unsigned int *adr; unsigned int msk; } BitSw32; // Bit Switch の初期設定 #define initBitSw(bitsw, address, location) \ do { \ (bitsw).adr = (address); \ (bitsw).msk = 0x01 << (location); \ } while(0) // Bit Switch へのデータ設定 #define setBitSw(bitsw, on_off) \ do { \ if (on_off) \ *(bitsw).adr |= (bitsw).msk; \ else \ *(bitsw).adr &= ~((bitsw).msk); \ } while(0) // Bit Switch のデータ参照 #define getBitSw(bitsw) \ ((*(bitsw).adr & (bitsw).msk) ? ON : OFF)