我正在研究一个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
结束。我知道这需要另一层次的间接,但我无法完全理解它。
答案 0 :(得分:3)
这很容易:
#define VECT(a, b) a##_##b
X##Y
会将X
和Y
连接为单个标识符。
在您的特定情况下,您需要将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的参数在传递之前会被扩展,这就是为什么这样做的原因。