C語言Bit位定義


C語言Bit定義注意點:

首先看一個C位域使用的官方例子(摘自MC9S12XS128.h):

/*** ATD0CTL23 - ATD 0 Control Register 23; 0x000002C2 ***/
typedef union {
  word Word;
   /* Overlapped registers: */
  struct {
    /*** ATD0CTL2 - ATD 0 Control Register 2; 0x000002C2 ***/
    union {
      byte Byte;
      struct {
        byte ACMPIE      :1;                                       /* ATD Compare Interrupt Enable */
        byte ASCIE       :1;                                       /* ATD Sequence Complete Interrupt Enable */
        byte ETRIGE      :1;                                       /* External Trigger Mode enable */
        byte ETRIGP      :1;                                       /* External Trigger Polarity */
        byte ETRIGLE     :1;                                       /* External Trigger Level/Edge control */
        byte ICLKSTP     :1;                                       /* Internal Clock in Stop Mode Bit */
        byte AFFC        :1;                                       /* ATD Fast Conversion Complete Flag Clear */
        byte             :1; 
      } Bits;
    } ATD0CTL2STR;
    #define ATD0CTL2                    _ATD0CTL23.Overlap_STR.ATD0CTL2STR.Byte
    #define ATD0CTL2_ACMPIE             _ATD0CTL23.Overlap_STR.ATD0CTL2STR.Bits.ACMPIE
    #define ATD0CTL2_ASCIE              _ATD0CTL23.Overlap_STR.ATD0CTL2STR.Bits.ASCIE
    #define ATD0CTL2_ETRIGE             _ATD0CTL23.Overlap_STR.ATD0CTL2STR.Bits.ETRIGE
    #define ATD0CTL2_ETRIGP             _ATD0CTL23.Overlap_STR.ATD0CTL2STR.Bits.ETRIGP
    #define ATD0CTL2_ETRIGLE            _ATD0CTL23.Overlap_STR.ATD0CTL2STR.Bits.ETRIGLE
    #define ATD0CTL2_ICLKSTP            _ATD0CTL23.Overlap_STR.ATD0CTL2STR.Bits.ICLKSTP
    #define ATD0CTL2_AFFC               _ATD0CTL23.Overlap_STR.ATD0CTL2STR.Bits.AFFC
    
    #define ATD0CTL2_ACMPIE_MASK        1U
    #define ATD0CTL2_ASCIE_MASK         2U
    #define ATD0CTL2_ETRIGE_MASK        4U
    #define ATD0CTL2_ETRIGP_MASK        8U
    #define ATD0CTL2_ETRIGLE_MASK       16U
    #define ATD0CTL2_ICLKSTP_MASK       32U
    #define ATD0CTL2_AFFC_MASK          64U
    /*** ATD0CTL3 - ATD 0 Control Register 3; 0x000002C3 ***/
    union {
      byte Byte;
      struct {
        byte FRZ0        :1;                                       /* Background Debug Freeze Enable Bit 0 */
        byte FRZ1        :1;                                       /* Background Debug Freeze Enable Bit 1 */
        byte FIFO        :1;                                       /* Result Register FIFO Mode */
        byte S1C         :1;                                       /* Conversion Sequence Length 1 */
        byte S2C         :1;                                       /* Conversion Sequence Length 2 */
        byte S4C         :1;                                       /* Conversion Sequence Length 4 */
        byte S8C         :1;                                       /* Conversion Sequence Length 8 */
        byte DJM         :1;                                       /* Result Register Data Justification */
      } Bits;
      struct {
        byte grpFRZ :2;
        byte     :1;
        byte     :1;
        byte     :1;
        byte     :1;
        byte     :1;
        byte     :1;
      } MergedBits;
    } ATD0CTL3STR;
    #define ATD0CTL3                    _ATD0CTL23.Overlap_STR.ATD0CTL3STR.Byte
    #define ATD0CTL3_FRZ0               _ATD0CTL23.Overlap_STR.ATD0CTL3STR.Bits.FRZ0
    #define ATD0CTL3_FRZ1               _ATD0CTL23.Overlap_STR.ATD0CTL3STR.Bits.FRZ1
    #define ATD0CTL3_FIFO               _ATD0CTL23.Overlap_STR.ATD0CTL3STR.Bits.FIFO
    #define ATD0CTL3_S1C                _ATD0CTL23.Overlap_STR.ATD0CTL3STR.Bits.S1C
    #define ATD0CTL3_S2C                _ATD0CTL23.Overlap_STR.ATD0CTL3STR.Bits.S2C
    #define ATD0CTL3_S4C                _ATD0CTL23.Overlap_STR.ATD0CTL3STR.Bits.S4C
    #define ATD0CTL3_S8C                _ATD0CTL23.Overlap_STR.ATD0CTL3STR.Bits.S8C
    #define ATD0CTL3_DJM                _ATD0CTL23.Overlap_STR.ATD0CTL3STR.Bits.DJM
    #define ATD0CTL3_FRZ                _ATD0CTL23.Overlap_STR.ATD0CTL3STR.MergedBits.grpFRZ
    
    #define ATD0CTL3_FRZ0_MASK          1U
    #define ATD0CTL3_FRZ1_MASK          2U
    #define ATD0CTL3_FIFO_MASK          4U
    #define ATD0CTL3_S1C_MASK           8U
    #define ATD0CTL3_S2C_MASK           16U
    #define ATD0CTL3_S4C_MASK           32U
    #define ATD0CTL3_S8C_MASK           64U
    #define ATD0CTL3_DJM_MASK           128U
    #define ATD0CTL3_FRZ_MASK           3U
    #define ATD0CTL3_FRZ_BITNUM         0U
    
  } Overlap_STR;</p><p>  struct {
    word FRZ0        :1;                                       /* Background Debug Freeze Enable Bit 0 */
    word FRZ1        :1;                                       /* Background Debug Freeze Enable Bit 1 */
    word FIFO        :1;                                       /* Result Register FIFO Mode */
    word S1C         :1;                                       /* Conversion Sequence Length 1 */
    word S2C         :1;                                       /* Conversion Sequence Length 2 */
    word S4C         :1;                                       /* Conversion Sequence Length 4 */
    word S8C         :1;                                       /* Conversion Sequence Length 8 */
    word DJM         :1;                                       /* Result Register Data Justification */
    word ACMPIE      :1;                                       /* ATD Compare Interrupt Enable */
    word ASCIE       :1;                                       /* ATD Sequence Complete Interrupt Enable */
    word ETRIGE      :1;                                       /* External Trigger Mode enable */
    word ETRIGP      :1;                                       /* External Trigger Polarity */
    word ETRIGLE     :1;                                       /* External Trigger Level/Edge control */
    word ICLKSTP     :1;                                       /* Internal Clock in Stop Mode Bit */
    word AFFC        :1;                                       /* ATD Fast Conversion Complete Flag Clear */
    word             :1; 
  } Bits;
  struct {
    word grpFRZ  :2;
    word         :1;
    word         :1;
    word         :1;
    word         :1;
    word         :1;
    word         :1;
    word         :1;
    word         :1;
    word         :1;
    word         :1;
    word         :1;
    word         :1;
    word         :1;
    word         :1;
  } MergedBits;
} ATD0CTL23STR;
extern volatile ATD0CTL23STR _ATD0CTL23 @(REG_BASE + 0x000002C2UL);
#define ATD0CTL23                       _ATD0CTL23.Word
#define ATD0CTL23_FRZ0                  _ATD0CTL23.Bits.FRZ0
#define ATD0CTL23_FRZ1                  _ATD0CTL23.Bits.FRZ1
#define ATD0CTL23_FIFO                  _ATD0CTL23.Bits.FIFO
#define ATD0CTL23_S1C                   _ATD0CTL23.Bits.S1C
#define ATD0CTL23_S2C                   _ATD0CTL23.Bits.S2C
#define ATD0CTL23_S4C                   _ATD0CTL23.Bits.S4C
#define ATD0CTL23_S8C                   _ATD0CTL23.Bits.S8C
#define ATD0CTL23_DJM                   _ATD0CTL23.Bits.DJM
#define ATD0CTL23_ACMPIE                _ATD0CTL23.Bits.ACMPIE
#define ATD0CTL23_ASCIE                 _ATD0CTL23.Bits.ASCIE
#define ATD0CTL23_ETRIGE                _ATD0CTL23.Bits.ETRIGE
#define ATD0CTL23_ETRIGP                _ATD0CTL23.Bits.ETRIGP
#define ATD0CTL23_ETRIGLE               _ATD0CTL23.Bits.ETRIGLE
#define ATD0CTL23_ICLKSTP               _ATD0CTL23.Bits.ICLKSTP
#define ATD0CTL23_AFFC                  _ATD0CTL23.Bits.AFFC
#define ATD0CTL23_FRZ                   _ATD0CTL23.MergedBits.grpFRZ</p><p>#define ATD0CTL23_FRZ0_MASK             1U
#define ATD0CTL23_FRZ1_MASK             2U
#define ATD0CTL23_FIFO_MASK             4U
#define ATD0CTL23_S1C_MASK              8U
#define ATD0CTL23_S2C_MASK              16U
#define ATD0CTL23_S4C_MASK              32U
#define ATD0CTL23_S8C_MASK              64U
#define ATD0CTL23_DJM_MASK              128U
#define ATD0CTL23_ACMPIE_MASK           256U
#define ATD0CTL23_ASCIE_MASK            512U
#define ATD0CTL23_ETRIGE_MASK           1024U
#define ATD0CTL23_ETRIGP_MASK           2048U
#define ATD0CTL23_ETRIGLE_MASK          4096U
#define ATD0CTL23_ICLKSTP_MASK          8192U
#define ATD0CTL23_AFFC_MASK             16384U
#define ATD0CTL23_FRZ_MASK              3U
#define ATD0CTL23_FRZ_BITNUM            0U

 

1、位域的分配

位域定義時的位地址分配並不是我們想象的那樣依次按從上而下,從低位到高位的順序排列起來的。他在分配時根據當前占用的位域和下一個位域能否合並為一個字節,來

判斷是否將當前位域獨立為一個字節,如果不注意這一點,很有可能位域分配時會存在只有幾個位就占用了一個字節的情況。比如:

struct{
 union{
    struct{
     unsigned  char bit0:4;
     unsigned  char bit1:1;
     unsigned  char bit2:3;
     unsigned  char bit4:4;
     unsinged  char bit5:6;
     unsigned  char bit6:6;
     
   }bitdata;
  unsigned char data[3];
 }example_unn;
}example_stt;

本來我們以為:4+1+3+4+6+6=24個bit占3個字節;

而實際上位域並沒有我們想象的那么靈活:

struct{
 union{
    struct{
     //byte1: 4+1+3=8(正好8位)
     unsigned  char bit0:4;
     unsigned  char bit1:1;
     unsigned  char bit2:3; 
     //byte2:因為4+6>8,bit4所以單獨占一個字節
     unsigned  char bit4:4;
     //byte3:同上bit5單獨占一個一節(6+6>8)
     unsinged  char bit5:6;
     //byte4:最后bit6再單獨占一個字節
     unsigned  char bit6:6;
     
   }bitdata;
  unsigned char data[4];//所以一共占用了4個字節
 }example_unn;
}example_stt;

C語言位域定義並不是太好用,當我們根據實際使用情況需要將內存那么分配時,位域將會失去他的便捷性,如上我們無法將bit4和bit5的低4位合並起來訪問,實際操作

我們還是要自己移位賦值,所以在制定協議時最好不要做跨字節的連續位定義。

2、位定位定義中的無名位域

無名位域可以用來填充使用,但無法訪問。

對於1中的情況,我們可以加入無名位域使其看起來更直觀的表示其位域地址分配的情況:

struct{
 union{
    struct{
     //byte1: 4+1+3=8(正好8位)
     unsigned  char bit0:4;
     unsigned  char bit1:1;
     unsigned  char bit2:3; 
     //byte2:因為4+6>8,bit4所以單獨占一個字節
     unsigned  char bit4:4;
     unsigned char :4;//無名位域,占位用,這樣你一下就可以看出,bit4單獨占一個字節!
     //byte3:同上bit5單獨占一個一節(6+6>8)
     unsigned  char bit5:6;
     unsigned char :2;
     //byte4:最后bit6再單獨占一個字節
     unsigned  char bit6:6;
     unsigned char :2;
   }bitdata;
  unsigned char data[4];//所以一共占用了4個字節
 }example_unn;
}example_stt;

還有一種特殊情況 unsigned  char:0 ,其中無名位域定義為0個位,就是說此處占一個字節位置。 

 

參考文檔:

1、C語言中結構體的位域(bit-fields  )

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM