Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用结构/联合组合_C_Pic_Pic18 - Fatal编程技术网

C 使用结构/联合组合

C 使用结构/联合组合,c,pic,pic18,C,Pic,Pic18,我在PIC18F87K90微控制器中使用c编程。我在创建一个结构变量(其中包含union)以便更容易地访问多个标志(大多数是1位标志,但有些是2位或3位标志)时遇到了一个问题 下面的代码运行良好。我使用模拟器检查每个成员的地址字节。union中的结构成员被分组在同一地址字节中,我希望这样,因为这些成员总共有8位,应该适合1字节。我还检查了以下地址: eeprom_标志。字节0,eeprom_标志。重置时间_字节。。。由于工会惯例,他们在同一地址。 我的问题是,我希望1位标志中的一个有两个可能的名

我在PIC18F87K90微控制器中使用c编程。我在创建一个结构变量(其中包含union)以便更容易地访问多个标志(大多数是1位标志,但有些是2位或3位标志)时遇到了一个问题

下面的代码运行良好。我使用模拟器检查每个成员的地址字节。union中的结构成员被分组在同一地址字节中,我希望这样,因为这些成员总共有8位,应该适合1字节。我还检查了以下地址: eeprom_标志。字节0,eeprom_标志。重置时间_字节。。。由于工会惯例,他们在同一地址。 我的问题是,我希望1位标志中的一个有两个可能的名称,即eeprom_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;

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

其思想是定义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所建议的,只需使用一个结构,然后#定义另一个结构的位字段

通常,如果使用|和&,编译器将生成较少的代码。除了or和ing之外,使用位还会产生大量的左右移位。
查看生成的代码时,您可能会很快感到困惑。

联合的最小大小是一个字节。你不能实现你所追求的。使用包含位字段和其他名称之一的结构的并集有一定的意义。为8位值指定7个(而不是1个)名称没有什么明显的好处。可能:
#定义output2\u time\u bit output\u time\u bit
Thx以获取建议。关于不使用#define、#ifdef、#endif,使用output2_time_位还是output2_time_位的决定将在我的微控制器初始化后做出,因此从技术上讲它是在运行时,尽管只是在初始化时。