从零件构建宏

时间:2013-10-25 12:49:07

标签: c macros c-preprocessor avr

我正在研究一个AVR,这些库包括使用预处理器TCD0_OVF_vect的设备中断向量,如TCD0_CCA_vect#defines,如下所示:

#define TCD0_OVF_vect_num  77
#define TCD0_OVF_vect      _VECTOR(77)  /* Overflow Interrupt */

它们还包括计时器对象:

typedef struct TC0_struct
{
  register8_t CTRLA;  /* Control  Register A */
  ...snip...
} TC0_t;

#define TCD0    (*(TC0_t *) 0x0900)  /* 16-bit Timer/Counter 0 */

我希望能够使用类似于TCD0的语法定义一个宏,该宏将命名的计时器对象TCD0_OVF_vect扩展为VECT(TCD0, OVF_vect)。例如:

ISR(VECT(TCD0, CCA_vect)) {}

转换为

ISR(TCD0_CCA_vect) {}

其中TCD0_CCA_vect是需要扩展的宏。

有办法做到这一点吗?

修改 另外,我会能够做到:

#define TIMER TCD0
#define VECT(a, b) ##SOMETHING##

然后能够使用VECT(TIMER, CCA_vect)并以TCD0_CCA_vect结束。我知道这需要另一层次的间接,但我无法完全理解它。

2 个答案:

答案 0 :(得分:3)

这很容易:

#define VECT(a, b)  a##_##b

X##Y会将XY连接为单个标识符。

在您的特定情况下,您需要将TCD0_CCA_vect连接到单个标识符TCD0_CCA_vect

请注意,这不适用于变量!

答案 1 :(得分:2)

这应该使用令牌连接来完成工作。

#define VECT(a, b) a ## _ ## b

来自评论:

  

是否可以使用#define TIMER TCD0然后使用VECT(TIMER, CCA_vect)

不是直接的,但是对于另一个级别的宏,答案是肯定的:

#define TIMER TCD0
#define PVECT(a, b) a ## _ ## b
#define VECT(a, b)  PVECT(a, b)

VECT(TIMER, CCA_vect)

该输出是:

TCD0_CCA_vect

传递给PVECT的参数在传递之前会被扩展,这就是为什么这样做的原因。