Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 从零件构建宏_C_Macros_C Preprocessor_Avr - Fatal编程技术网

C 从零件构建宏

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 */

我正在开发一个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 */
  ...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
作为变量。