1. 程式人生 > >C語言中利用共用體、結構體、位域實現位操作

C語言中利用共用體、結構體、位域實現位操作

編寫過51(MCU)程式的同學都知道51架構的MCU支援位操作,這是一個很方便的特性,在讀取/修改暫存器某位的值時非常方便快捷。但其他架構的MCU大多都不支援該特性,即不支援位操作,所在在對暫存器中某一位進行操作的時候都是and/or兩個操作共同使用,在編寫程式時非常麻煩。在查找了大量資料後,筆者得出了本文中提到的一種折中方法。
名詞解釋:
共用體(union)表示幾個變數共用一個記憶體位置,在不同的時間儲存不同的資料型別和不同長度的變數。在union中,所有的共用體成員共用一個空間,並且同一時間只能儲存其中一個成員變數的值。
結構體(struct)是由一系列具有相同型別或不同型別的資料構成的資料集合,也叫結構。

位域是指資訊在儲存時,並不需要佔用一個完整的位元組, 而只需佔幾個或一個二進位制位。


在程式中定義這樣一個共用體(union):

  1. typedefunion FLAG  
  2. {  
  3.     WORD flags;  
  4.     struct
  5.     {  
  6.         unsigned int flag_bit0:1;  
  7.         unsigned int flag_bit1:1;  
  8.         unsigned int flag_bit2:1;  
  9.         unsigned int flag_bit3:1;  
  10.         unsigned int flag_bit4:1;  
  11.         unsigned int flag_bit5:1;  
  12.         unsigned int flag_bit6:1;  
  13.         unsigned int flag_bit7:1;  
  14.         unsigned int flag_bit8:1;  
  15.         unsigned int flag_bit9:1;  
  16.         unsigned int flag_bit10:1;  
  17.         unsigned int flag_bit11:1;  
  18.         unsigned int flag_bit12:1;  
  19.         unsigned int
     flag_bit13:1;  
  20.         unsigned int flag_bit14:1;  
  21.         unsigned int flag_bit15:1;  
  22.     }bit;  
  23. }Flag;  

上面的共用體給出了一個16位暫存器的定義,在操作中,既可以對整個暫存器一起操作,也可以針對某一位進行操作。

例如,在程式中定義一個共用體的物件:

Flag stFlag;

stFlag.flags = 0xa5;

int P0_0 = stFlag.bit.flag_bit0;

int P0_1 = stFlag.bit.flag_bit1;

// 實際中位域的排序根據編譯器以及具體系統的儲存模式相關

/*************************************************************************************************
    檔名:global.h
    作  者:lihonglin
    版  本:V1.0
    說  明:全域性變數標頭檔案。
    修改記錄:
*************************************************************************************************/
#ifndef _GLOBAL_H_
#define _GLOBAL_H_
#include <mc96f7616a.h>


#ifdef MyDef
#define EXTERN    //定義變數
#else
#define EXTERN extern  //宣告變數
#endif






#define  ON 1
#define  OFF 0
#define  OK 1
#define  FAIL0
#define  TRUE1
#define  FALSE0
#defineB8_0 0x01
#defineB8_1 0x02
#defineB8_2 0x04
#defineB8_3 0x08
#defineB8_4 0x10
#defineB8_5 0x20
#defineB8_6 0x40
#defineB8_7 0x80
#defineB8_LSBB8_0
#defineB8_MSBB8_7
///IO/////////
#defineAlarm_Mode_Stand0//待機狀態
#defineAlarm_Mode_Set1//設定狀態
#defineAlarm_Mode_Off2//關閉狀態
#defineAlarm_Mode_Ring3//響狀態


struct Bit_Flag_Byte {
unsigned char B0:1;
unsigned char B1:1;
unsigned char B2:1;
unsigned char B3:1;
unsigned char B4:1;
unsigned char B5:1;
unsigned char B6:1;
unsigned char B7:1;
};
//MyDef BITS kk;
//
union Bit_Field_Byte {
unsigned char byte;
struct Bit_Flag_Byte bits;
}; 
/*
EXTERN union Bit_Field_Byte flag1;//
#defineflag1.bit.B0
#defineflag1.bit.B1
#defineflag1.bit.B2
#defineflag1.bit.B3
#defineflag1.bit.B4
#defineflag1.bit.B5
#defineflag1.bit.B6
#defineflag1.bit.B7
*/
EXTERN union Bit_Field_Byte flag1;//
EXTERN union Bit_Field_Byte flag2;// 
EXTERN union Bit_Field_Byte flag3;// 
EXTERN union Bit_Field_Byte flag4;//  
#definefalarm_onflag1.bits.B0
#definefshan_setflag1.bits.B1
#definefshan_salarmflag1.bits.B2
#definefshan_col1flag1.bits.B3
#definefblue_onflag1.bits.B4
#definefblue_okflag1.bits.B5
#definefshan_alarmflag1.bits.B6
#definefxia_onflag1.bits.B7


#definefxia_rangeflag1.bits.B0
#definefxia_refflag1.bits.B1
#definefalarm_signleflag1.bits.B2
#definefbm_zhuanflag1.bits.B3
#definefalarm_tanflag1.bits.B4
#defineled_levelflag1.bits.B5
#defineflcd_ref_timeflag1.bits.B6
#defineflcd_ref_alarmflag1.bits.B7 


#defineflcd_ref_biaoflag1.bits.B0




EXTERN unsigned char G_gettime[7],G_getalarm[2],G_getflag;//ds1302時間,鬧鐘,標誌位
EXTERN unsigned char G_settime[5],G_setalarm[2],voice_level,G_shizhi,G_lcdmode,alarm_mode;
#endif