在嵌入式的設計中,經常有判斷旗標要被使用。
但使用 char 或是 _Bool 這些宣告則太過浪費記憶體,
而C語言中有個方法可以只需要一個位元就可以做。
這個方法稱為 Bit Field ,現在較新的 C 語言書都不太提到,
確定有談到這個方法的書目前只看過 K & R 與 Pointers on C。
做 Bit Field 時必須使用 struct
例如:
先寫好
在 MSP430 操作的情況下,使用 Bit Field 直接操作硬體位元,為了不要再多定義記憶體來搬運所以操作略有點不同。例如:
struct SFRbitDef{
先建好結構後,將結構指向實際配合硬體的位址:
#define P2input ((struct SFRbitDef *) 0x28 );
#define P1output ((struct SFRbitDef *) 0x21 );
後面的 0x28 和 0x21 分別是搭配硬體用的記憶體位址。
於是存取的時候,以這樣寫成:
if ( (P2input->B1) == 0 ) { P1output->B4 = 1; }
// 此段程式是讀取 P2 的 B1接腳,若該接腳電位為零則將 P1 的 B4 接腳輸出為 1 。
同樣的也可以這樣應用:
P1output->B4 = ~(P1output->B4);
// 直接簡單的將該位元反向
Read More
但使用 char 或是 _Bool 這些宣告則太過浪費記憶體,
而C語言中有個方法可以只需要一個位元就可以做。
這個方法稱為 Bit Field ,現在較新的 C 語言書都不太提到,
確定有談到這個方法的書目前只看過 K & R 與 Pointers on C。
做 Bit Field 時必須使用 struct
例如:
先寫好
struct Flag{
unsigned F1 : 1;
unsigned F2 : 1;
unsigned F3 : 1;
unsigned F4 : 1;
unsigned F5 : 1;
unsigned F6 : 1;
unsigned F7 : 1;
unsigned F8 : 1;
};
最尾數的1代表使用一個bit。
然後要使用時則宣告
struct Flag flagexample;
那麼這個叫做flagexample的變數在記憶體內的實況則會是
如此設定和宣告過後,就可以這樣用:
flagexample.F2 = 1;
flagexample.F6 = 0;
並且可以應用在判斷是,例如:
if ( flagexample.F6 == 1 ) {.........}
如果與 union 聯合 混合使用。例如:
union{
unsigned char AllMsg;
struct {
unsigned bit0:1 ;
unsigned bit1:1 ;
unsigned bit2:1 ;
unsigned bit3:1 ;
unsigned bit4:1 ;
unsigned bit5:1 ;
unsigned bit6:1 ;
unsigned bit7:1 ;
};
} Message;
這段程式代表直接宣告一個變數叫做 Message,程式操作時
Message.AllMsg = 0x80;
可等同於
Message.bit7 = 1; Message.bit6 = 0; Message.bit5 = 0; Message.bit4 = 0;
Message.bit3 = 0; Message.bit2 = 0; Message.bit1 = 0; Message.bit0 = 0;
--------------------------------------------------------------------------------------
在 MSP430 操作的情況下,使用 Bit Field 直接操作硬體位元,為了不要再多定義記憶體來搬運所以操作略有點不同。例如:
struct SFRbitDef{
unsigned B0 : 1;
unsigned B1 : 1;
unsigned B2 : 1;
unsigned B3 : 1;
unsigned B4 : 1;
unsigned B5 : 1;
unsigned B6 : 1;
unsigned B7 : 1;
};先建好結構後,將結構指向實際配合硬體的位址:
#define P2input ((struct SFRbitDef *) 0x28 );
#define P1output ((struct SFRbitDef *) 0x21 );
後面的 0x28 和 0x21 分別是搭配硬體用的記憶體位址。
於是存取的時候,以這樣寫成:
if ( (P2input->B1) == 0 ) { P1output->B4 = 1; }
// 此段程式是讀取 P2 的 B1接腳,若該接腳電位為零則將 P1 的 B4 接腳輸出為 1 。
同樣的也可以這樣應用:
P1output->B4 = ~(P1output->B4);
// 直接簡單的將該位元反向