Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Условное выражение внутри #define
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
ViKo
Есть ли возможность в C сделать что-то подобное:
Код
#define TEST(A,B,MULT)    \
    A = B<<(#if (#MULT == "ONE") 1    \
            #elif (#MULT == "TWO") 2);
MrYuran
Цитата(ViKo @ Mar 21 2012, 15:15) *
Есть ли возможность в C сделать что-то подобное:
Код
#define TEST(A,B,MULT)    \
    A = B<<(#if (#MULT == "ONE") 1    \
            #elif (#MULT == "TWO") 2);

Можно.
Через составные макросы и конкатенацию ##
Код
#define TEST(A,B,MULT)    TEST##MULT(A,B)
#define TESTONE(A,B)
#define TESTTWO(A,B)
Сергей Борщ
Вроде бы нет.
Задача не до конца понятна, возможно тут нужен не препроцессор?
CODE
typedef enum
{
    ZERO,
    ONE,
    TWO
} mult_t;

inline int TEST(int b, mult_t mult) { return b << mult; }
С остальным справится оптимизатор.
Dog Pawlowa
Цитата(ViKo @ Mar 21 2012, 14:15) *
Есть ли возможность в C

pragma inline дает вполне стабильные результаты.
ViKo
Задачка упрощена, конечно. Хотелось для конфигурации портов STM32L151 написать универсальное макро для всех регистров. А их там много. В некоторых для задания режима одного бита порта требуется один бит в регистре, в большинстве - 2, для альтернативных функций - 4. Думаю, как бы по имени регистра задать нужное количество сдвигов.
Может, и зря. Хочу понять, можно ли. Надо попробовать решение MrYuran.
MrYuran
Цитата(ViKo @ Mar 21 2012, 15:34) *
Надо попробовать решение MrYuran.

Это не моё, а Аскольда Волкова sm.gif
ViKo
Цитата(MrYuran @ Mar 21 2012, 14:37) *
Это не моё, а Аскольда Волкова sm.gif

Скорее уж K&R, а Аскольд Волков смог "осилить" sm.gif
sasamy
Цитата(ViKo @ Mar 21 2012, 15:15) *
Есть ли возможность в C сделать что-то подобное:
Код
#define TEST(A,B,MULT)    \
    A = B<<(#if (#MULT == "ONE") 1    \
            #elif (#MULT == "TWO") 2);


Код
#define ONE 1
#define TWO 2            

#define TEST(A,B,MULT)    \
    A = B<<MULT;
ViKo
Цитата(sasamy @ Mar 21 2012, 15:47) *
Код
#define ONE 1
#define TWO 2            

#define TEST(A,B,MULT)    \
    A = B<<MULT;

Мне нужно было и имя ONE/TWO оставить и использовать (нельзя переопределять), и количество сдвигов по имени задать.

Конкретно, вот что вышло:
Код
#define GPIO_INIT(PORT,REG,\
    BT15,BT14,BT13,BT12,BT11,BT10,BT9,BT8,BT7,BT6,BT5,BT4,BT3,BT2,BT1,BT0) \
    GPIO_##REG##_INIT(PORT,BT15,BT14,BT13,BT12,BT11,BT10,BT9,BT8,BT7,BT6,BT5,BT4,BT3,BT2,BT1,BT0)

#define GPIO_MODER_INIT(PORT,\
    MD15,MD14,MD13,MD12,MD11,MD10,MD9,MD8,MD7,MD6,MD5,MD4,MD3,MD2,MD1,MD0) \
    GPIO##PORT->MODER = \
    (MD15<<30|MD14<<28|MD13<<26|MD12<<24|MD11<<22|MD10<<20|MD9<<18|MD8<<16| \
    MD7<<14|MD6<<12|MD5<<10|MD4<<8|MD3<<6|MD2<<4|MD1<<2|MD0)

#define GPIO_OTYPER_INIT(PORT,\
    OT15,OT14,OT13,OT12,OT11,OT10,OT9,OT8,OT7,OT6,OT5,OT4,OT3,OT2,OT1,OT0) \
    GPIO##PORT->OTYPER = \
    (OT15<<15|OT14<<14|OT13<<13|OT12<<12|OT11<<11|OT10<<10|OT9<<9|OT8<<8| \
    OT7<<7|OT6<<6|OT5<<5|OT4<<4|OT3<<3|OT2<<2|OT1<<1|OT0)
...
neiver
А как вам такое решение.
Там, примеры для AVR приведены, но в архиве есть демо для STM32.
ViKo
Цитата(neiver @ Mar 21 2012, 16:45) *
А как вам такое решение

Не хватило усердия разобраться. Зато узнал много нового.
Судя по комментариям, все слишком сложно.
В библиотеке Std_Periph_Lib тоже куча функций используется, структуры для инициализации... якобы, с целью упрощения. Только ну его в болото, такое упрощение. Когда вместо изучения битов в регистрах приходится лазить по исходникам библиотеки, а потом все равно лезть за битами в дейташит. Не говоря уже о том ужасном количестве кода, во что превращается инициализация порта, в частности.
ViKo
Вот какую... какое... "сочинил":
CODE

/* Биты конфигурации портов (* - после сброса) */
typedef enum {
MD_IN, MD_GPO, MD_AF, MD_AN // Input(*), Output, Alternate, Analog
} GPIO_MODE_t; // GPIO Mode Type

typedef enum {
OT_PP, OT_OD // Push-Pull*, Open-Drive
} GPIO_OTYPE_t; // GPIO Output Type

typedef enum {
SP_400K, SP_2M, SP_10M, SP_40M // 400kHz(*), 2MHz, 10MHz, 40MHz
} GPIO_OSPEED_t; // GPIO Output Speed Type

typedef enum {
PL_NP, PL_PU, PL_PD // No_Pull(*), Pull-Up, Pull-Down
} GPIO_PUPD_t; // GPIO Pull-Up_Pull-Down Type

typedef enum {
AF_SYSTEM, // AF0 - SYSTEM*
AF_TIM2, // AF1 - TIM2
AF_TIM3, AF_TIM4 = 2, // AF2 - TIM3/4,
AF_TIM9, AF_TIM10 = 3, AF_TIM11 = 3, // AF3 - TIM9/10/11
AF_I2C1, AF_I2C2 = 4, // AF4 - I2C1/2
AF_SPI1, AF_SPI2 = 5, // AF5 - SPI1/2
AF_AF6, // AF6 - _
AF_USART1, AF_USART2 = 7, AF_USART3 = 7, // AF7 - USART1/2/3
AF_AF8, // AF8 - _
AF_AF9, // AF9 - _
AF_USBFS, // AF10 - USBFS
AF_LCD, // AF11 - LCD
AF_AF12, // AF12 - _
AF_AF13, // AF13 - _
AF_RI, // AF14 - RI
AF_EVENTOUT // AF15 - SYSTEM (EVENTOUT)
} GPIO_AFLH_t; // GPIO Alternate Functions

#define GPIO_INIT(PORT, \
MDR0,OTR0,SPR0,PLR0,AFR0, \
MDR1,OTR1,SPR1,PLR1,AFR1, \
MDR2,OTR2,SPR2,PLR2,AFR2, \
MDR3,OTR3,SPR3,PLR3,AFR3, \
MDR4,OTR4,SPR4,PLR4,AFR4, \
MDR5,OTR5,SPR5,PLR5,AFR5, \
MDR6,OTR6,SPR6,PLR6,AFR6, \
MDR7,OTR7,SPR7,PLR7,AFR7, \
MDR8,OTR8,SPR8,PLR8,AFR8, \
MDR9,OTR9,SPR9,PLR9,AFR9, \
MDR10,OTR10,SPR10,PLR10,AFR10, \
MDR11,OTR11,SPR11,PLR11,AFR11, \
MDR12,OTR12,SPR12,PLR12,AFR12, \
MDR13,OTR13,SPR13,PLR13,AFR13, \
MDR14,OTR14,SPR14,PLR14,AFR14, \
MDR15,OTR15,SPR15,PLR15,AFR15); \
GPIO##PORT->MODER = ((uint32_t) \
MDR15<<30|MDR14<<28|MDR13<<26|MDR12<<24|MDR11<<22|MDR10<<20|MDR9<<18|MDR8<<16| \
MDR7<<14|MDR6<<12|MDR5<<10|MDR4<<8|MDR3<<6|MDR2<<4|MDR1<<2|MDR0); \
GPIO##PORT->OTYPER = ((uint32_t) \
OTR15<<15|OTR14<<14|OTR13<<13|OTR12<<12|OTR11<<11|OTR10<<10|OTR9<<9|OTR8<<8| \
OTR7<<7|OTR6<<6|OTR5<<5|OTR4<<4|OTR3<<3|OTR2<<2|OTR1<<1|OTR0); \
GPIO##PORT->OSPEEDR = ((uint32_t) \
SPR15<<30|SPR14<<28|SPR13<<26|SPR12<<24|SPR11<<22|SPR10<<20|SPR9<<18|SPR8<<16| \
SPR7<<14|SPR6<<12|SPR5<<10|SPR4<<8|SPR3<<6|SPR2<<4|SPR1<<2|SPR0); \
GPIO##PORT->PUPDR = ((uint32_t) \
PLR15<<30|PLR14<<28|PLR13<<26|PLR12<<24|PLR11<<22|PLR10<<20|PLR9<<18|PLR8<<16| \
PLR7<<14|PLR6<<12|PLR5<<10|PLR4<<8|PLR3<<6|PLR2<<4|PLR1<<2|PLR0); \
GPIO##PORT->AFR[0] = ((uint32_t) \
AFR7<<28|AFR6<<24|AFR5<<20|AFR4<<16|AFR3<<12|AFR2<<8|AFR1<<4|AFR0); \
GPIO##PORT->AFR[1] = ((uint32_t) \
AFR15<<28|AFR14<<24|AFR13<<20|AFR12<<16|AFR11<<12|AFR10<<8|AFR9<<4|AFR8); \

/* Пример применения */
GPIO_INIT(A,
MD_GPO, OT_PP, SP_400K, PL_NP, AF_SYSTEM, // PA0
MD_AF, OT_PP, SP_400K, PL_PU, AF_USART2, // PA1
MD_AF, OT_PP, SP_400K, PL_PU, AF_TIM2, // PA2
MD_IN, OT_PP, SP_400K, PL_PD, AF_SYSTEM, // PA3
MD_AN, OT_PP, SP_400K, PL_NP, AF_SYSTEM, // PA4 - ADC4
MD_AN, OT_PP, SP_400K, PL_NP, AF_SYSTEM, // PA5 - ADC5
MD_AN, OT_PP, SP_400K, PL_NP, AF_SYSTEM, // PA6 - ADC6
MD_AN, OT_PP, SP_400K, PL_NP, AF_SYSTEM, // PA7 - ADC7
MD_AF, OT_PP, SP_10M, PL_NP, AF_SYSTEM, // PA8 - MSO
MD_AF, OT_PP, SP_10M, PL_NP, AF_USART1, // PA9
MD_AF, OT_PP, SP_10M, PL_NP, AF_USART1, // PA10
MD_AF, OT_PP, SP_10M, PL_NP, AF_USART1, // PA11
MD_AF, OT_PP, SP_10M, PL_NP, AF_USART1, // PA12
MD_AF, OT_PP, SP_10M, PL_NP, AF_SYSTEM, // PA13 - JTMS-SWDAT
MD_AF, OT_PP, SP_10M, PL_NP, AF_SYSTEM, // PA14 - JTCK-SWCLK
MD_AF, OT_PP, SP_10M, PL_NP, AF_SYSTEM); // PA15 - JTDI

Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.