在结构中使用联合的目的是啥?

Posted

技术标签:

【中文标题】在结构中使用联合的目的是啥?【英文标题】:What purpose to use union in struct?在结构中使用联合的目的是什么? 【发布时间】:2017-08-24 01:20:00 【问题描述】:

我目前正在为嵌入式 UART 程序中的 uart sn-p 代码而苦苦挣扎。

然后我在分析代码时遇到了我无法理解的事情。

第一季度。如果在“结构”中使用“联合”。这样使用有什么好处和目的?

#define     __IO    volatile   

typedef struct 
  union 
  __IO  uint32_t RR;
  __IO  uint32_t TR;
  __IO  uint32_t DL;
  __IO  uint32_t RR_TR_DL;
  ;
  union 
  __IO  uint32_t DH;
  __IO  uint32_t IR;  
  __IO  uint32_t DH_IER;
  ;
 UART_TypeDef;

第二季度。在“struct”中的“struct”中使用“union”的情况下。像这样使用有什么好处和目的是什么?

typedef struct 
  union 
  struct
    __IO   uint32_t CTRLR0; 
    __IO   uint32_t SSI_COMP_VERSION;  
    union 
    __IO   uint32_t DR;              
    __IO   uint32_t DR0;            
    ;
    __IO   uint32_t DR1;            
    __IO   uint32_t RSVD_2;       
  ;
  uint8_t RESERVED[0x1000];     
  ;
 SSI_TypeDef;

【问题讨论】:

这当然是一个奇特的union。请注意,DR 和 `DR0` 原则上具有相同的值。 请引用描述由该 typdef 表示的寄存器的手册。根据具体情况,您可能会发现一些可以被视为“RR”、“TR”或“DL”的东西,然后是可以被视为“DH”或“IR”的东西。 【参考方案1】:

第一种情况基本上是字段名称的“别名”。 UART_TypeDef 类型由两个uint32_t 字段组成,第一个字段可以称为RRTRDLRR_TR_DL 中的任何一个。第二个字段同上,可以是DHIRDH_IER

第二种情况SSI_TypeDefinner联合类似,由三个uint32_t字段CTRLR0/SSI_COMP_VERSIONDR/DR0DR1/RSVD_2组成(在所有情况下) , 任一名称均可用于字段)。

但由于与uint8_t RESERVED[0x1000] 联合,整个结构的大小为 4K。


例如,如果同一基础字段可以作为RRTR 访问,则别名很有用,具体取决于上下文。例如,根据您是读取还是写入位置,设备可能具有不同的行为。

例如,假设您写入到给定地址(内存映射 I/O 操作),以向另一端表明您已准备好读取(能够接收数据)。进一步假设读取那个完全相同的位置会让你知道你是否能够传输。

首先,让我们设置内存映射的 I/O 地址(比如0xf000):

UART_TypeDef *utd = (UART_TypeDef *)0xf000; // very shifty :-)

现在both这些语句引用了相同的内存地址:

int transmitReady = utd->TR; // Can I transmit?
utd->RR = 1;                 // Tell other end it can send.

能够为相同的底层事物使用不同的名称有助于提高可读性。

【讨论】:

为了理解,你能告诉我一些例子的用法吗?

以上是关于在结构中使用联合的目的是啥?的主要内容,如果未能解决你的问题,请参考以下文章

c语言中uint是啥意思

c语言中uint是啥意思

C语言中的(uint32)1<<10 是啥意思?

联合查询、表连接查询、子查询三种查询的特点和注意事项各是啥

检查联合实例之间是不是相等的正确方法是啥?

ado.net 和 dapper 之间的交集/联合是啥?