2014-09-05 2 views
0

Я пытаюсь упростить запись моих встроенных программ в C. Как создать макрос, который мог бы принимать любое число или параметры из 2?Несколько параметров в макросе

настоящее время у меня это:

#define P_PIN_HIGH(pin_letter, pin_num)   (PORT##pin_letter |= (1 << pin_num)) 
#define PIN_HIGH(...)   P_PIN_HIGH(__VA_ARGS__) 

И я могу использовать это как так:

#define PIN_TEST A, 0 // Every pin gets defined this way. 

PIN_HIGH(PIN_TEST);   // Set this pin to high. 

Но, я хотел бы быть в состоянии передать любое количество контактов (они должны иметь то же самое письмо) к макросу, например, так:

#define PIN_TEST  A, 0 
#define PIN_TEST1 A, 1 
#define PIN_TEST2 A, 2 

PIN_HIGH(PIN_TEST, PIN_TEST1, PIN_TEST2); 

таким образом, скомпилированный код, будет выглядеть следующим образом:

PORTA |= ((1<<0) | (1<<1) | (1<<2)); 

Является ли это выполнимым?

+0

ли вы имеете в виду "число PARAMATERS"> = 2? В этом случае это возможно. Синтаксис: '#define MACRO (A, B, ...)', а затем внутри макроса снова получается часть, соответствующая '...', с '__VA_ARGS__'. – pablo1977

+0

Возможный дубликат [Переменные аргументы в макросе с использованием многоточия] (http://stackoverflow.com/questions/11514201/variable-arguements-in-macro-using-ellipsis) –

+0

Нет, не дубликат. Большим> = 2, я просто имел в виду, что по крайней мере один вывод должен быть передан макросу. – user1806687

ответ

0

Ваш макрос P_PIN_HIGH(), кажется, принимает только два аргумента. В вашем variadic macro PIN_HIGH вы передаете три пары аргументов, которые, согласно определению этого макроса, будут переданы в качестве аргументов P_PIN_HIGH (который ожидает только 2 аргумента). Похоже, вы хотели бы перебрать пары аргументов в свой макрос P_PIN_HIGH(), явно передав количество пар аргументов.

+1

Да, правильно, я бы хотел повторить. Как я могу это сделать? – user1806687

1

не очень. Если вы можете использовать C++, то с шаблонами очень легко.

template <volatile char *port_, size_t bit_number_> 
struct port_descriptor 
{ 
    static constexpr size_t bit_number = bit_number_; 
    static volatile char *const port; 
}; 
template <volatile char *port_, size_t bit_number_> 
volatile char *const port_descriptor<port_, bit_number_>::port = port_; 

typedef port_descriptor<&PORTA, 0> PIN_TEST; 

template <class ...args> 
char get_set_port_value(bool new_value); 

template <class ...args> 
void set_port_value(bool new_value); 

template <volatile char *port_, size_t bit_number_> 
char get_set_port_value<port_descriptor<port_, bit_number_>>(bool new_value) 
{ 
    char v = *port_; 
    if(new_value) 
     return v | 1 << bit_number_; 
    return v & ~(1 << bit_number_); 
} 

template <volatile char *port_, size_t bit_number_, class ...Args> 
char get_set_port_value<port_descriptor<port_, bit_number_>, Args...>(bool new_value) 
{ 
    char v = get_set_port_value<Args...>(); 
    if(new_value) 
     return v | 1 << bit_number_; 
    return v & ~(1 << bit_number_); 
} 

template <volatile char *port_, size_t bit_number_, class ...Args> 
void set_port_value<port_descriptor<port_, bit_number_>, Args...>(bool new_value) 
{ 
    char v = get_set_port_value<port_descriptor<port_, bit_number_>, Args...>(new_value); 
    *port_ = v; 
} 

, то вы можете сделать set_port_value<PIN_TEST>(true);

+0

Нет, это программа для микроконтроллера. – user1806687

+0

какой микроконтроллер? – programmerjake

+0

8-битный AVR, было бы излишним использовать C++. – user1806687