我正在为avr gpio编写一个驱动程序,我有一个函数,它接受一个枚举输入。我做了一个宏,在端口名和“uuu”连接之后调用这个函数,这样我就可以一直使用initPort(port a,1,…)。

#define initPort(port,mask,dir,pullup) GPIO_Init(port ## __,mask,dir,pullup)

typedef enum {
PORTA__,
PORTB__,
PORTC__,
PORTD__
} PORT;

void GPIO_Init(PORT p, uint8_t pins, Direction dir,uint8_t pullup) {
switch (p) {
    case PORTA__:

现在,当我想使用这个函数时,我使用了:initPort(PORTA,1,…)这个函数可以正常工作。
问题是当我想使用类似于:
#define LED_PORT PORTA
initPort(LED_PORT,1,...)

现在发生的是GPIO_Init的参数现在是LED_PORT_u,而不是PORTA__
有可能解决这个问题吗?还是我必须用另一种方法?

最佳答案

实际上,可以通过强制预处理器在以下时间之前执行额外的过程来完成此操作:

#define initPortS(port,mask,dir,pullup) GPIO_Init(port ## __,mask,dir,pullup)
#define initPort(...) initPortS(__VA_ARGS__)
#define LED_PORT PORTA

initPort(LED_PORT,1,2,3);

这样可以:
第一关:
initPort(LED_PORT,1,2,3); -> initPortS(PORTA,1,2,3);

第二遍:
initPortS(PORTA,1,2,3); -> GPIO_Init(PORTA__,1,2,3);

Here is a demo
可能的陷阱:
如果PORTA是已定义的符号,则在第二次传递时它也将被展开。所以如果你有这样一条线
#define PORTA XXX

在代码的某个地方,它将扩展到
GPIO_Init(XXX__,1,2,3);

10-08 13:29