简体   繁体   中英

C Macro concatenation as function argument

I have a problem using a macro as a function parameter.

I have this macro:

#define PD13 GPIOD, GPIO_Pin_13

GPIOD and GPIO_Pin_13 are macros too.

#define GPIO_Pin_13 ((uint16_t)0x2000)
#define GPIOD  ((GPIO_TypeDef *) GPIOD_BASE)

in which GPIOD_BASE is a memory address.

I'm using it as argument for this function:

PinType initPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) {
PinType pin;
if (GPIOx == GPIOA) {
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
} else if (GPIOx == GPIOB) {
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
} else if (GPIOx == GPIOC) {
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
} else if (GPIOx == GPIOD) {
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
} else {
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
}
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOx, &GPIO_InitStructure);
GPIO_ResetBits(GPIOx, GPIO_Pin);
pin.GPIO_Reg = GPIOx;
pin.GPIO_Pin = GPIO_Pin;
pin.status = 1;
return pin;
}
PinType p1
p1 = initPin(PD13);

In this way everything works well, but if I try to add an argument to the initPin function, like:

void initPin(PinType *pin, GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) {
if (GPIOx == GPIOA) {
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
} else if (GPIOx == GPIOB) {
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
} else if (GPIOx == GPIOC) {
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
} else if (GPIOx == GPIOD) {
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
} else {
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
}
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOx, &GPIO_InitStructure);
GPIO_ResetBits(GPIOx, GPIO_Pin);
pin->GPIO_Reg = GPIOx;
pin->GPIO_Pin = GPIO_Pin;
pin->status = 1;
}

PinType p1;
initPin(&p1, PD13);

The arguments are messed up and are incorrect.

Is there any way so I can use a macro for passing a part of the arguments while the others are passed normally?

Is there any way so I can use a macro for passing a part of the arguments while the others are passed normally?

No. Macro expansion is entirely textual and there are no mechanisms to suppress expansion of selected arguments.

You could, however, define different macros to achieve a similar effect:

#define PD13_2args GPIOD, GPIO_Pin_13
#define PD13_1arg  GPIO_Pin_13
initPin(PD13_2args);
initPin(&p1, PD13_1arg);

You might also want to read about variadic macros , a feature available with C99 and later, in conjunction with variadic functions (eg like printf ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM