文章转载自:https://www.eemaker.com/us_union.html
在单片机软件编程中,结构体和枚举类型都很常用到,联合体相对来用的就比较少。那么结构体和联合体的区别到底在哪里?我们先列举一个结构体如下:
struct test
{
int office;
char teacher[5];
};
struct test a;
我们再定义一个联合体,如下:
union test
{
int office;
char teacher[5];
};
union test b;
假如在该变量都定义在stm8的单片机编程中,那么一个int变量占用4个字节,一个char变量占用一个字节。这样结构体a占用的就是4+5=9个字节。联合体b占用的是5个字节。这样就很清晰的看出来结构体和联合体的区别到底在哪里。结构体中每一个成员都要占用相应的空间,联合体总得空间就是看占用最大空间的那个成员。char teacher[5] 占用5个字节,office占用4个字节。所以最终b结构体就占用5个字节。当然联合体还有一个特性就是office和teacher[5]的空间是共享的,简单理解就是操作office就会改变teacher的前四个字节的值。
好了,现在联合体的概念搞明白了。那么他在单片机软件里面到底有什么妙用?正如开头所述,使用联合体定义变量可以让你进行位操作。请看下面一段简单的代码:
union test
{
unsigned char ODR;
struct
{
unsigned char bit0:1,
bit1:1,
bit2:1,
bit3:1,
bit4:1,
bit5:1,
bit6:1,
bit7:1;
};
};
union test c;
可以看到union c 里面有两个成员一个是char ODR,另一个是包含一个unsigned char型变量的结构体,这里面的unsigned char型变量被分成了8个1bit。这样这个结构体和ODR就是共用同一个空间。相对整个字节操作就直接操作ODR。例如:c.ODR=0xff; 如果相对某一位操作就可以c.bit0=1;所以假如ODR是个控制io口输出的寄存器,就可以简单的使用c.bitx=x(0或者1);这样来对每一位进行直接赋值。
在有的ram资源少的单片机,能节省ram空间也是很重要的。那么union有时候同样可以发挥作用。在写代码的时候会经常遇到开关型变量(开关型变量也就是只有0或者1),一般在stm8里面就是这么定义的:
uint8_t flag1=0;
uint8_t flag2=0;
uint8_t flag3=0;
…………
这样每一个flag都会占用一个字节的ram空间。假如这样的flag变量很多我们就可以使用union来节省空间。代码如下:
union uflag
{
unsigned char flag;
struct
{
unsigned char flag0:1,
flag1:1,
flag2:1,
flag3:1,
flag4:1,
flag5:1,
flag6:1,
flag7:1;
};
};
union uflag flg;