C 使用并集表示寄存器

C 使用并集表示寄存器,c,unions,C,Unions,我正在尝试使用联合设置HCS12处理器的内部寄存器。以下是我目前拥有工会的方式: union byte{ struct{ unsigned int B0: 1; unsigned int B1: 1; unsigned int B2: 1; unsigned int B3: 1; unsigned int B4: 1; unsigned int B5: 1; unsigned

我正在尝试使用联合设置HCS12处理器的内部寄存器。以下是我目前拥有工会的方式:

union byte{
    struct{
        unsigned int B0: 1;
        unsigned int B1: 1;
        unsigned int B2: 1;
        unsigned int B3: 1;
        unsigned int B4: 1;
        unsigned int B5: 1;
        unsigned int B6: 1;
        unsigned int B7: 1;
    }idv;
    unsigned int All: 8;
};

union allPurpose{
    struct {
        union byte A;
        union byte B;
    } AB;
    unsigned int D: 16;
};
问题是,当我使用int All将A初始化为170,将B初始化为187时。D应为43707,但为170。我知道嵌套的联合是有效的,但由于某种原因它不起作用。如果有人能看到一些错误,并能提供帮助,我们将不胜感激

编辑:以下是在中使用union的代码

HCS12.accumulator.AB.A.All=0xAA;
HCS12.accumulator.AB.B.All=0xBB;
printf("\nReg A: %d",HCS12.accumulator.AB.A.All);
printf("\nReg B: %d",HCS12.accumulator.AB.B.All);
printf("\nReg D: %d",HCS12.accumulator.D);

Union-allPurpose只是在另一个结构中。

您不能假定
Union字节a
联合字节B在内存中连续打包

(事实上,在现代体系结构中,由于它们的大小只有一个字节,所以它们不太可能出现)

具体的打包安排取决于编译器和平台的选择。典型的排列是4字节的打包,这意味着您的结构如下所示:

 struct {
     union byte A;
     /*Three bytes of packing*/
     union byte B;
 } AB;
  • 首先,您不应该在嵌入式系统中使用位字段,例如。您的问题很可能是由于编译器的位顺序指定不当(可能是Codewarrior?)

    我强烈建议使用以下100%可移植语法:

    #define PEAR    (*(volatile uint8_t*)0x000Au)
    #define NOACCE  0x80u
    #define PIPOE   0x20u
    #define NECLK   0x10u
    #define LSTRE   0x08u
    #define RDWE    0x04u
    
  • 在使用嵌入式系统时,不应使用C中的默认基元数据类型(如unsigned int)。改用stdint.h中的uint16_t等

  • 将一个8位成员和一个16位成员联合起来是没有任何意义的。这可能是问题的原因

  • 通常,在映射硬件寄存器时避免使用结构/联合,因为编译器可能会在结构内部的任何位置引入填充。由于HCS12是一个很好的内核,它不关心对齐,因此在您的特定情况下,这不会是一个问题

编辑


您的printf代码看起来可疑。printf()使用参数升级到
int
。改为查看调试器内存映射。您的变量有哪些值?

一般来说,这是一个很好的建议。然而,HCS12是一个有点现代的架构,它根本不在乎对齐。您可以在内存中的任何位置读取8位或16位访问。现在有没有办法将打包安排设置为使其连续?这不是标准C。您必须阅读编译器文档。例如,在MSVC2012中,您可以使用#pragma pack指令。好的,谢谢您的帮助。我将尝试找出GNU-GCC编译器是否有类似的设置。可能是我声明的方式,我没有使用HCS12来运行代码。这些并集表示/模拟HCS12处理器内部寄存器。@Nathan那么你是在使用PC?那样的话,恐怕你对你正在做的事一无所知。。。HCS12是一个16位big-endian CPU。你的普通电脑是一个32/64位的小端CPU。您的代码在HCS12和PC之间是100%不可移植的。我知道这一点。这段代码是我在电脑上模拟HCS12的程序的一部分。很抱歉,这可能是我造成混淆的原因。@Nathan你需要从代码中后退一步,然后开始阅读。那么这段代码实际上是在什么平台上运行的?不,我分别设置了a和B。D未设置,但应为0xAABB。请参阅我的答案。通过在调试器中查看结构实例的内存布局来确定其正确性(或其他)。它在运行Windows 7的PC上运行,我正在使用GNU-GCC编译器。它不打算在HCS12上运行。