我希望有人可能对如何控制/指定宏扩展的顺序有所了解。这是上下文:
// 32 bit increments, processor has registers for set, clear and invert
#define CLR_OFF 1
#define SET_OFF 2
#define INV_OFF 3
#define SET(reg,bits) *((volatile unsigned long*)(& reg+SET_OFF)) = bits
//Now if I use this I can do it quite nicely with
#define STATUS_LED 0x0040;
SET(LATB, STATUS_LED); // LATB is port of the LED.
实际上,我最近不得不移动很多硬件,所以我决定像这样将 LATB 信息与 STATUS_LED 分组......
#define STATUS_LED_PORT LATB
#define STATUS_LED_MASK 0x0040;
#define STATUS_LED STATUS_LED_PORT, STATUS_LED_MASK
//And I try to use it via
SET( STATUS_LED );
但是很可惜,LATB,0x0040 被传递给了 SET 宏的参数 1。当不用作宏时,此方法可以正常工作:
inline void SET(u32_t *reg, u32_t bits) { ((volatile u32_t *) (((u32_t)reg) + SET_OFF*4 )) = bits; }
//Change the STATUS_LED macro to
#define STATUS_LED &STATUS_LED_PORT, STATUS_LED_MASK
SET( STATUS_LED); //Works great!
但不幸的是,我的编译器没有看到需要内联函数并导致 6 条指令设置寄存器而不是 4 条指令,因此在位碰撞时使用它是不可预测的。
我希望有人可能知道首先扩展 STATUS_LED 宏的方法,例如:
SET( ##STATUS_LED )
目前我继续前进的解决方案是有两个宏 SET 和 SETRM(设置寄存器,掩码),但我觉得应该有一个解决方案,因为 SET 的代码看起来像......
#define SETRM(reg,bits) ...
#define SET(args) SETRM(args) //WHY WOULD THIS GET EXPANDED HERE??
最后,我的处理器的编译器不支持宏的 n 参数,我想我可能可以使用它,但是唉 :(。
非常感谢您抽出宝贵的时间,如果有任何想法,我将不胜感激,我可以继续前进,但是如果我可以在任何地方都使用 SET 会更加简洁。