2016年6月6日 星期一

Published 下午3:43 by with 0 comment

[筆記] C語言中使用單一位元的做法:Bit Field 位元欄位

在嵌入式的設計中,經常有判斷旗標要被使用。
但使用 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);
// 直接簡單的將該位元反向


      edit

0 意見:

張貼留言