1

我正在开发一个 AVR,这些库包括设备中断向量,例如TCD0_OVF_vectTCD0_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. 我知道这需要另一个级别的间接性,但我不能完全理解它。

4

2 回答 2

3

这很容易:

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

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

在您的特定情况下,您需要将TCD0,_和连接CCA_vect到单个标识符TCD0_CCA_vect中。

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

于 2013-10-25T12:52:04.490 回答
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 的参数在传递之前会被扩展,这就是为什么这样做。

于 2013-10-25T12:53:19.203 回答