内部联合结构,uart状态

时间:2019-03-25 10:20:02

标签: c struct embedded union

我正在使用MPLABX IDE MCC生成的代码。在UART驱动程序中的某个时刻,存在以下用于UART状态的代码。

typedef union {
    struct {
      unsigned perr : 1;
      unsigned ferr : 1;
      unsigned oerr : 1;
      unsigned reserved : 5;
    };
    uint8_t status;
}uart1_status_t;

据我了解,并集内部有2种类型,1种结构和1种8位无符号变量。我有两个问题:

  1. 实际上是什么... perr:1;在这里做什么?没有指示类型,只有未签名的是什么,什么是“:1”?这不是给perr的价值吗?当我在C编译器上进行尝试时,我看到它们实际上是状态变量的一部分。 perr和ferr分别是0和1位,而oerr是4位?为什么?
  2. 该结构没有“实例”,那么如何访问它?我对本节感到困惑。由于是一个联合,这些位和状态变量存储在同一存储位置,因此,每当我尝试访问状态时,是否还意味着访问这些perr,ferr,oerr值?是吗?

2 个答案:

答案 0 :(得分:3)

  1. 这是声明硬件寄存器的常见(错误)方法。该结构是一个位字段,各个成员引用8位寄存器中的位。该语法允许您访问单个位或整个寄存器。

    在这种情况下,该结构是匿名的,因此如果您拥有uart1_status_t u1;,则可以以u1.perr而不是u1.somename.perr的身份访问位。匿名结构是C11的功能,尽管在这种情况下,它可能是他们在C11之前使用的一些非标准扩展。

    它们使用unsigned的意思是unsigned int,因为这是用于位字段的默认类型。但是请注意,该代码是完全不可移植的,并且依赖于位域的某些编译器实现。

  2. 在其他地方,您会看到类似volatile uart1_status_t* UART1_STATUS = ...的地址,它指向一个绝对地址。 (就像使用@这样的非标准语法一样)。由于它们是内存映射的硬件寄存器,因此它们已在MCU中放置,因此您无需为其分配空间。

答案 1 :(得分:1)

  1. 这个问题是重复的,答案是“它们是位字段,冒号后面的数字以位为单位指定字段的宽度”。 Here is an earlier question with a good answer
  2. 可能在某个地方有一个宏,它提供了转换为正确类型的寄存器的地址,并提供了处理器文档中的名称。