我目前正在努力处理嵌入式 UART 程序中的 uart 片段代码。
然后我在分析代码时发现了我无法理解的地方。
Q1。如果在“struct”中使用“union”。这样有什么好处和用途?
#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;
最佳答案
第一种情况基本上是字段名称的“别名”。 UART_TypeDef
类型由两个 uint32_t
组成字段,第一个字段可以称为 RR
中的任何一个, TR
, DL
或RR_TR_DL
。第二个字段也是如此,可以是 DH
, IR
或DH_IER
.
第二个案例,SSI_TypeDef
,与内部 union 类似,由三个 uint32_t
组成。字段,CTRLR0/SSI_COMP_VERSION
, DR/DR0
和DR1/RSVD_2
(在所有情况下,字段都可以使用任一名称)。
但是由于与 uint8_t RESERVED[0x1000]
的 union ,整个结构的大小为 4K .
例如,如果可以通过 RR
访问相同的基础字段,则别名很有用。或TR
,取决于上下文。例如,设备可能有不同的行为,具体取决于您是读取还是写入位置。
例如,您写入到给定地址(内存映射 I/O 操作),以向另一端表明您已准备好读取(能够接收数据)。进一步假设读取完全相同的位置会让您知道是否能够传输。
首先,让我们设置所述内存映射 I/O 地址(假设它位于 0xf000
):
UART_TypeDef *utd = (UART_TypeDef *)0xf000; // very shifty :-)
现在这两个语句都引用相同内存地址:
int transmitReady = utd->TR; // Can I transmit?
utd->RR = 1; // Tell other end it can send.
能够对同一底层事物使用不同的名称可以提高可读性。
关于c++ - 在结构体中使用 union 的目的是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45851520/