使用结构/联合组合

问题描述

我正在PIC18F87K90单片机中使用c编程。我在创建结构变量(在其中包含并集)时遇到问题,以便可以轻松访问多个标志(大多数是1位标志,而有些是2位或3位)。

下面的代码运行良好。我使用模拟器来检查每个成员的地址字节。联合内部结构的成员被分组在相同的地址字节中,这是我期望的,因为成员共有8位,应该适合1字节。我还要检查以下地址: eeprom_flag.byte0,eeprom_flag.reset_time_byte ...等,由于使用工会,它们位于同一地址。 我的问题是我想为一个1位标志eepeep_flag.output_time_bit使用两个可能的名称。我想为其命名(但完全相同的变量位,相同的地址)。我尝试使用union来做到这一点(请参见下面的注释行)。但是,这样做将破坏我的代码,使结构的成员不再位于相同的地址中。我的目标是进行寻址,如上图所示。

typedef struct
{
    //buffer index 0
    union
    {
        struct
        {
            uint8_t reset_time_bit:1;
//            union
//            {
                uint8_t output_time_bit:1;      //shared address
//                uint8_t output2_time_bit:1;
//            };
            uint8_t count_mode_bit:3;
            uint8_t input_mode_bit:1;
            uint8_t count_speed_bit:2;
        };
        uint8_t byte0;
        uint8_t reset_time_byte;
        uint8_t output_time_byte;
        uint8_t output2_time_byte;
        uint8_t count_mode_byte;
        uint8_t input_mode_byte;
        uint8_t count_speed_byte;
    };
} eeprom_flag_t;
extern volatile eeprom_flag_t   eeprom_flag;

Expected mapping

解决方法

尽管我不明白您为什么要这么做,但以下内容可能会满足您的要求。

这个想法是,您定义2个位域(struct),这些域以使您满意的方式重叠(union)。

union
{
    struct { uint8_t output_time_bit:1;} ;
    struct { uint8_t output2_time_bit:1;} ;
}
,

理论上,您可能想要的东西是可能的,但实际上,没有供应商编写过可以做到这一点的编译器。通常,并集与字节边界对齐。在某些编译器上,它们与2、4、8或16个字节的边界对齐。

您必须重新声明整个结构才能实现所需的功能。无需将联合放在结构中-联合可以直接用于typedef中。另外,如果您不命名内部结构,则可能无法查看调试器中的值。调试器对此很气质-有时可以,有时不能。

typedef union
{
    struct
    {
        uint8_t reset_time_bit:1;
        uint8_t output_time_bit:1;      //shared address
        uint8_t count_mode_bit:3;
        uint8_t input_mode_bit:1;
        uint8_t count_speed_bit:2;
    } bits1;
    struct
    {
        uint8_t reset_time_bit:1;
        uint8_t output2_time_bit:1;
        uint8_t count_mode_bit:3;
        uint8_t input_mode_bit:1;
        uint8_t count_speed_bit:2;
    } bits2;
    uint8_t byte0;
    ...
} eeprom_flag_t;

或者,如@Mike所建议的,仅具有一种结构并#define另一种结构的位域。

通常,如果|,则编译器将生成较少的代码。和&被使用。使用位除了会导致or-ing和and-ing之外,还会产生许多左右移位。 查看生成的代码时,您很快就会非常困惑。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...