C语言 | 联合体使用实例

1024G 嵌入式资源大放送!包括但不限于C/C++、单片机、Linux等。关注微信公众号【嵌入式大杂烩】,回复1024,即可免费获取!

大家好,我是ZhengN。本次给分享联合体的一些知识。

联合体/共用体的使用

C语言中,联合体/共用体可以实现同一个内存空间中存储不同的数据类型(不是同时存储)。利用这个特性可以在一些情况下给我们提供便利。

比如验证大小端有很多种方法,使用联合体也可以:

#include <stdio.h>

union test
{
    int a;
    char b;
}test_u;

int main(void)
{
    test_u.a = 0x12345678;
    if (0x78 == test_u.b)
    {
        printf("Little endian\n");
    }
    else
    {
        printf("Big endian\n");
    }
    return 0;
}

再比如前两天群里有朋友问:在寄存器操作上,位域看起来似乎挺合适,但为什么库代码都基本没有使用呢?

其实TI的库中有使用,是结合共用体来使用的:

所有的寄存器被封装成联合体类型的,联合体里边的成员是一个32bit的整数及一个结构体,该结构体以位域的形式体现。这样就可以达到直接操控寄存器的某些位了。

比如,我们要设置PA0引脚的GPAQSEL1寄存器的[1:0]两位都为1,则我们只操控两个bit就可以很方便的这么设置:

GpioCtrlRegs.GPAQSEL1.bit.GPIO0 = 3

或者直接操控整个寄存器:

GpioCtrlRegs.GPAQSEL1.all |=0x03 

再比如当系统中有很多用于描述同一功能的状态变量时,传统做法可能是:

volatile uint16 iuvp = 0; // 输入欠压
volatile uint16 iovp = 0; // 输入过压
volatile uint16 iocp = 0; // 输入过流
volatile uint16 motp = 0; // 功率模块过温
volatile uint16 oovp = 0; // 输出过流

/* 判断异常及处理 */
if ((iuvp != 0) || 
 (iovp != 0) || 
 (iocp != 0) || 
 (motp != 0) || 
 (oovp != 0) 
 )
{
 // do something
}

当我们在做状态判断时,这样写下来就感觉很冗余。

换种方式:可以把这些状态变量规整到一个联合体中,用位域来描述。(以下这段代码来自:https://blog.csdn.net/weixin_44474431/article/details/102795568)

typedef union SYSTEM_FAULT{
   uint16 all;
   struct {
      uint16 iuvp:  1; // 输入欠压
      uint16 iovp:  1; // 输入过压
      uint16 iocp:  1; // 输入过流
      uint16 motp:  1; // 功率模块过温
      uint16 oovp:  1; // 输出过流
      uint16 oocp:  1; // 输出过流
      uint16 oopp:  1; // 过功率故障
      uint16 excu:  1; // 电流采样零漂过大
      uint16 cotp:  1; // CPU过温
      uint16 ilrv:  1; // 输入极性错误
  }bit;
}SYSTEM_FAULT_STRUCT;

然后状态判断可以这么做:

volatile SYSTEM_FAULT_STRUCT gPSM_FAULT;
if(gPSM_FAULT.all != 0)
{
 // do something
}

简介明了了很多。关于位域的介绍可阅读往期笔记:【C语言笔记】位域

猜你喜欢

goto用的多吗?

例说嵌入式实用知识之JSON数据

1024G 嵌入式资源大放送!包括但不限于C/C++、单片机、Linux等。关注微信公众号【嵌入式大杂烩】,回复1024,即可免费获取!

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式大杂烩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值