2

我正在尝试更改 lpc2138 的 IAR 特定头文件,以便它可以与 Visual Studio 2008 一起编译(以启用兼容的单元测试)。

我的问题涉及将寄存器定义转换为独立于硬件(不在内存地址)

“IAR 安全宏”是:

#define __IO_REG32_BIT(NAME, ADDRESS, ATTRIBUTE, BIT_STRUCT) \
                    volatile __no_init ATTRIBUTE union       \
                     {                                       \
                       unsigned long NAME;                   \
                       BIT_STRUCT NAME ## _bit;              \
                     } @ ADDRESS
//declaration
//(where __gpio0_bits is a structure that names 
//each of the 32 bits as P0_0, P0_1, etc)
__IO_REG32_BIT(IO0PIN,0xE0028000,__READ_WRITE,__gpio0_bits);
//usage
IO0PIN = 0x0xAA55AA55;
IO0PIN_bit.P0_5 = 0;

这是我可比较的“硬件独立”代码:

#define __IO_REG32_BIT(NAME, BIT_STRUCT)\
                    volatile union \
                     {                                 \
                       unsigned long NAME;             \
                       BIT_STRUCT NAME##_bit;      \
                     } NAME;
//declaration
__IO_REG32_BIT(IO0PIN,__gpio0_bits);
//usage
IO0PIN.IO0PIN = 0xAA55AA55;
IO0PIN.IO0PIN_bit.P0_5 = 1;

这可以编译并且可以工作,但很明显我的“硬件独立”用法与“IAR 安全”用法不匹配。

如何更改宏,以便可以像在 IAR 中一样使用 IO0PIN?我觉得这是一个简单的匿名工会问题,但多次尝试和变体已被证明是不成功的。也许 IAR GNU 编译器支持匿名联合,而 vs2008 不支持。

谢谢你。

4

3 回答 3

1

好的,伙计们,这最终为我工作:

#define __IO_REG32_BIT(NAME, BIT_STRUCT)\
    volatile union\
    {\
        unsigned long NAME;\
        BIT_STRUCT NAME##_bit;\
    } NAME##_type;

__IO_REG32_BIT(IO0PIN,__gpio0_bits);        

#define IO0PIN IO0PIN_type.IO0PIN
#define IO0PIN_bit IO0PIN_type.IO0PIN_bit

现在我可以在我的代码中使用以下代码进行单元测试:

IO0PIN = 0xFFFFFFFF;
IO0PIN_bit.P0_5 = 1;

预处理器会将其替换为:

IO0PIN_type.IO0PIN = 0xFFFFFFFF;
IO0PIN_type.IO0PIN_bit.P0_5 = 1;
于 2010-04-28T18:58:46.533 回答
0

执行此操作的常用方法是使用仅将所需地址转换为适当类型的宏:

#define __IO_REG32_BIT(NAME, BIT_STRUCT) \
    typedef volatile union \
    { \
        unsigned long NAME##_value: \
        BIT_STRUCT NAME##_bit; \
    } NAME##_type

__IO_REG32_BIT(IO0PIN, __gpio0_bits);
#define IO0PIN (*(IO0PIN_type *)0xE0028000)

现在IO0PIN可以按照您的描述使用。但是,请注意,我必须重命名内部字段并键入名称以避免与宏名称冲突IO0PIN。您当然可以根据自己的喜好重命名。

于 2010-04-23T18:17:04.533 回答
0

我知道这不是答案,但我没有足够的声誉来编辑问题。我希望这可能有助于澄清。如果你把所有的宏都去掉,Alan_m 想要得到的是一个匿名联合,如下所示:

volatile union {
   u32 IO0PIN;
   u16 IO0PIN_bit;
};

可以这样引用:

void test( void )
{
   IO0PIN = 0x0xAA55AA55;
   IO0PIN_bit.P0_5 = 0;
}

这适用于 IAR 编译器,但会导致 VC++ 编译器出现编译器错误

错误 C2646:全局匿名联合必须声明为静态

请注意,这是来自 VS2005,因此它可能与 VS2008 略有不同。

我想 Alan_m 的所有代码都已经按照 IAR 标准编写,并且必须进行修改以使用他想要避免的命名联合。

于 2010-04-23T22:39:58.907 回答