C语言中利用共用体、结构体、位域实现位操作

编写过51(MCU)程序的同学都知道51架构的MCU支持位操作,这是一个很方便的特性,在读取/修改寄存器某位的值时非常方便快捷。但其他架构的MCU大多都不支持该特性,即不支持位操作,所在在对寄存器中某一位进行操作的时候都是and/or两个操作共同使用,在编写程序时非常麻烦。在查找了大量资料后,笔者得出了本文中提到的一种折中方法。
名词解释:
共用体(union)表示几个变量共用一个内存位置,在不同的时间保存不同的数据类型和不同长度的变量。在union中,所有的共用体成员共用一个空间,并且同一时间只能储存其中一个成员变量的值。
结构体(struct)是由一系列具有相同类型或不同类型的数据构成的数据集合,也叫结构。
位域是指信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。


在程序中定义这样一个共用体(union):

[cpp]  view plain copy
  1. typedef union 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


#ifdef MyDef
#define EXTERN    //定义变量
#else
#define EXTERN extern  //声明变量
#endif






#define   ON 1
#define   OFF 0
#define   OK 1
#define   FAIL 0
#define   TRUE 1
#define   FALSE 0
#define B8_0 0x01
#define B8_1 0x02
#define B8_2 0x04
#define B8_3 0x08
#define B8_4 0x10
#define B8_5 0x20
#define B8_6 0x40
#define B8_7 0x80
#define B8_LSB B8_0
#define B8_MSB B8_7
///IO/////////
#define Alarm_Mode_Stand 0 //待机状态
#define Alarm_Mode_Set 1 //设置状态
#define Alarm_Mode_Off 2 //关闭状态
#define Alarm_Mode_Ring 3 //响状态


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; //
#define flag1.bit.B0
#define flag1.bit.B1
#define flag1.bit.B2
#define flag1.bit.B3
#define flag1.bit.B4
#define flag1.bit.B5
#define flag1.bit.B6
#define flag1.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; //  
#define falarm_on flag1.bits.B0
#define fshan_set flag1.bits.B1
#define fshan_salarm flag1.bits.B2
#define fshan_col1 flag1.bits.B3
#define fblue_on flag1.bits.B4
#define fblue_ok flag1.bits.B5
#define fshan_alarm flag1.bits.B6
#define fxia_on flag1.bits.B7


#define fxia_range flag1.bits.B0
#define fxia_ref flag1.bits.B1
#define falarm_signle flag1.bits.B2
#define fbm_zhuan flag1.bits.B3
#define falarm_tan flag1.bits.B4
#define led_level flag1.bits.B5
#define flcd_ref_time flag1.bits.B6
#define flcd_ref_alarm flag1.bits.B7  


#define flcd_ref_biao flag1.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

你可能感兴趣的:(编程)