单片机 程序 共用体使用简单例子

  在C语言中,还有另外一种和结构体非常类似的语法,叫做共用体(Union),它的定义格式为:

union 共用体名{
    成员列表
};

共用体有时也被称为联合或者联合体,这也是 Union 这个单词的本意。之前在写C程序的时候很少用到,最近发现共用体倒是非常好用,以下将最近应用到的例子记录一下

  1. 定义一个既能按位域寻址也可按字节寻址的新变量类型
    //定义位
    typedef union { 
      unsigned char BYTE;			//可以按字节寻址 
      struct { 
        unsigned char BIT0        :1;                                        
        unsigned char BIT1        :1;                                        
        unsigned char BIT2        :1;                                        
        unsigned char BIT3        :1;                                       
        unsigned char BIT4        :1;                                      
        unsigned char BIT5        :1;                                        
        unsigned char BIT6        :1;                                       
        unsigned char BIT7        :1;                                     
      } BIT;						//定义一个只能按位域寻址的新变量类型                                         
    } BITFIELD;						//定义一个既能按位域寻址也可按字节寻址的新变量类型
    
     BITFIELD Flag;        //定义一个共用体变量
    
    #define f_time_1ms    Flag.BIT.BIT0
    #define f_time_2ms    Flag.BIT.BIT1
    #define f_time_3ms    Flag.BIT.BIT2
    #define f_time_4ms    Flag.BIT.BIT3
    #define f_time_5ms    Flag.BIT.BIT4
    #define f_time_6ms    Flag.BIT.BIT5
    #define f_time_7ms    Flag.BIT.BIT6
    #define f_time_8ms    Flag.BIT.BIT7
    
    /*清所有标志位时*/
    Flag.BYTE=0x00;

    2.利用共用体的占用内存空间按最大字节变量的特性,用在EEPROM上读写超过1字节的变量倒是很合适

typedef unsigned long   	uint32;      /* Unsigned 32 bit value */

typedef unsigned int		uint16;      /* Unsigned 16 bit value */

typedef unsigned char		uint8;       /* Unsigned 8  bit value */

typedef union
{
	uint16 Data;           //16位变量
	struct { 
        uint8  LOW;         //低8位
        uint8  HIGH;        //高8位
        }Data_Buff;
	
}EEPROM_TypeDef;

//定义变量
EEPROM_TypeDef EEPROM;

//超过8bit的变量,存eeprom时,如果用共用体的话就可以直接存入,而不需要进行转换

write_eeprom(ADDR_DATA_HIGH,EEPROM.Data_Buff.HIGH);//存变量高8位

write_eeprom(ADDR_DATA_LOW,EEPROM.Data_Buff.LOW);  //存变量低8位

//读取也一样方便,只要从eeprom读取出高低8位的数据,不进行合并也能得到16位的变量

EEPROM.Data_Buff.HIGH=read_eeprom(ADDR_DATA_HIGH);//存变量高8位

EEPROM.Data_Buff.LOW =read_eeprom(ADDR_DATA_LOW);  //存变量低8位

3.数码管扫描上倒是也挺好用的。

#define SEG_COM_SIZE  4

#define		EnCom(port)		port=0
#define		DisCom(port)	port=1

#define		EnSeg(port)		port=1
#define		DisSeg(port)	port=0

typedef union
{
	uint8 Buff;           
	struct { 
    unsigned char BIT0        :1;                                        
    unsigned char BIT1        :1;                                        
    unsigned char BIT2        :1;                                        
    unsigned char BIT3        :1;                                       
    unsigned char BIT4        :1;                                      
    unsigned char BIT5        :1;                                        
    unsigned char BIT6        :1;                                       
    unsigned char BIT7        :1;                                     
	} BIT;
	
}Data_TypeDef;

typedef struct { 
 uint8 ComCnt;					//数码管公共端计数
 uint8 Buff[SEG_COM_SIZE]; 		//存数码管要显示的数据
 Data_TypeDef Data;				//显示数据,每一位代表数码管的一个段
}SegDisplay_TypeDef;

SegDisplay_TypeDef SegDisp; 

void SEG_Display(void)
{
//---关闭所有段位 进行消隐  

    //关闭段的映射io口	
	DisSeg(P_SEG_A);			
	DisSeg(P_SEG_B);
	DisSeg(P_SEG_C);
	DisSeg(P_SEG_D);
	DisSeg(P_SEG_E);
	DisSeg(P_SEG_F);
	DisSeg(P_SEG_G);
	DisSeg(P_SEG_H);	

    //关闭位的映射io口
	DisCom(P_SEG_COM1);		
	DisCom(P_SEG_COM2);
	DisCom(P_SEG_COM3);
	DisCom(P_SEG_COM4);
	
	//先存储要显示的数据,这样对应的位也会得到数据
	SegDisp.Data.Buff=SegDisp.Buff[SegDisp.ComCnt];

	//数码管段 显示  
	P_SEG_A=SegDisp.Data.BIT.BIT0;
	P_SEG_B=SegDisp.Data.BIT.BIT1;
	P_SEG_C=SegDisp.Data.BIT.BIT2;
	P_SEG_D=SegDisp.Data.BIT.BIT3;
	P_SEG_E=SegDisp.Data.BIT.BIT4;
	P_SEG_F=SegDisp.Data.BIT.BIT5;
	P_SEG_G=SegDisp.Data.BIT.BIT6;
	P_SEG_H=SegDisp.Data.BIT.BIT7;

    /*开启 相应的位*/
    switch(SegDisp.ComCnt)
    {
        case 0:EnCom(P_SEG_COM1); break;
        case 0:EnCom(P_SEG_COM2); break;
        case 0:EnCom(P_SEG_COM3); break;
        case 0:EnCom(P_SEG_COM4); break;
    }

	//数码管 位选改变
	if(++SegDisp.ComCnt>=SEG_COM_SIZE) SegDisp.ComCnt=0;
}

 

 

 

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值