我目前正在努力使用嵌入式UART程序中的uart代码段。
然后,当我分析代码时,我发现了我无法理解的内容。
Q1。如果使用" union" in" struct"。这样做的好处和用途是什么?
#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;
Q2。如果使用" union" in" struct" in" struct"。有什么好处,有什么用途?
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;
答案 0 :(得分:2)
第一种情况基本上是#34;别名"字段名称。 UART_TypeDef
类型包含两个uint32_t
字段,第一个字段可以称为RR
,TR
,DL
或RR_TR_DL
中的任意一个。同样适用于第二个字段,可以是DH
,IR
或DH_IER
。
第二种情况SSI_TypeDef
与内部联盟类似,由三个uint32_t
字段组成,CTRLR0/SSI_COMP_VERSION
,DR/DR0
和DR1/RSVD_2
(在所有情况下,任一名称都可以用于字段)。
但由于与uint8_t RESERVED[0x1000]
结合,整个结构的大小为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.
能够为相同的基础事物使用不同的名称有助于提高可读性。