C 从零件构建宏
我正在开发一个AVR,这些库包括设备中断向量,如C 从零件构建宏,c,macros,c-preprocessor,avr,C,Macros,C Preprocessor,Avr,我正在开发一个AVR,这些库包括设备中断向量,如TCD0_OVF_vect和TCD0_CCA_vect使用预处理器,定义如下: #define TCD0_OVF_vect_num 77 #define TCD0_OVF_vect _VECTOR(77) /* Overflow Interrupt */ 它们还包括计时器对象: typedef struct TC0_struct { register8_t CTRLA; /* Control Register A */
TCD0_OVF_vect
和TCD0_CCA_vect
使用预处理器,定义如下:
#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 */
我希望能够定义一个宏,使用类似于vect(TCD0,OVF\u vect)
的语法将命名计时器对象TCD0
扩展到TCD0\u OVF\u vect
。例如:
ISR(VECT(TCD0, CCA_vect)) {}
皈依
ISR(TCD0_CCA_vect) {}
其中,TCD0\u CCA\u vect
是一个需要扩展的宏
有办法做到这一点吗
编辑:
此外,我希望能够做到:
#define TIMER TCD0
#define VECT(a, b) ##SOMETHING##
然后能够使用VECT(TIMER,CCA\u VECT)
并最终使用TCD0\u CCA\u VECT
。我知道这需要另一个间接的层次,但我不能把我的头脑完全围绕它。这很容易:
#define VECT(a, b) a##_##b
X##Y
将X
和Y
连接为一个标识符
在您的特定情况下,您需要将TCD0
、和CCA\u vect
连接到单个标识符TCD0\u CCA\u vect
请注意,这不适用于变量 这很简单:
#define VECT(a, b) a##_##b
X##Y
将X
和Y
连接为一个标识符
在您的特定情况下,您需要将TCD0
、和CCA\u vect
连接到单个标识符TCD0\u CCA\u vect
请注意,这不适用于变量 这应该使用令牌连接完成工作
#define VECT(a, b) a ## _ ## b
在评论中:
是否可以使用#定义计时器TCD0
,然后使用VECT(计时器,CCA\u 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的参数在传递之前会展开,这就是为什么这样做。这应该使用令牌连接完成这项工作
#define VECT(a, b) a ## _ ## b
在评论中:
是否可以使用#定义计时器TCD0
,然后使用VECT(计时器,CCA\u 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的参数在传递之前会展开,这就是为什么这样做。我在上面添加了一个编辑。简而言之,是否可以使用#定义定时器TCD0
,然后使用VECT(TIMER,CCA\u VECT)
?@CarsonDarling,不幸的是没有办法。将令牌粘贴在一起(使用##
)发生在宏扩展之前,因此您不能让宏向量(a,b)
首先扩展a
(在您的示例中是计时器
),然后使用#
创建一个新令牌。这是我所担心的,特别是由于定时器
需要扩展一次到TCD0
,但不是一直扩展到0x900
,然后粘贴到TCD0_CCA_vect
,然后再次扩展。谢谢你的帮助@卡森,亲爱的,你说得绝对正确。为了帮助减少重复代码,您可能想找到一种方法,用数组和一些逻辑将a
和b
映射到a_b
常量,这样您就可以循环它,或者将a
和b
作为变量。我在上面添加了一个编辑。简而言之,是否可以使用#定义定时器TCD0
,然后使用VECT(TIMER,CCA\u VECT)
?@CarsonDarling,不幸的是没有办法。将令牌粘贴在一起(使用##
)发生在宏扩展之前,因此您不能让宏向量(a,b)
首先扩展a
(在您的示例中是计时器
),然后使用#
创建一个新令牌。这是我所担心的,特别是由于定时器
需要扩展一次到TCD0
,但不是一直扩展到0x900
,然后粘贴到TCD0_CCA_vect
,然后再次扩展。谢谢你的帮助@卡森,亲爱的,你说得绝对正确。为了帮助减少重复代码,您可能希望找到一种方法,使用数组和一些逻辑将a
和b
映射到a_b
常量,这样您就可以在其上循环,或者将a
和b
作为变量。