Перейти к содержанию
    

Условное выражение внутри #define

Есть ли возможность в C сделать что-то подобное:

#define TEST(A,B,MULT)    \
    A = B<<(#if (#MULT == "ONE") 1    \
            #elif (#MULT == "TWO") 2);

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Есть ли возможность в 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)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вроде бы нет.

Задача не до конца понятна, возможно тут нужен не препроцессор?

typedef enum
{
    ZERO,
    ONE,
    TWO
} mult_t;

inline int TEST(int b, mult_t mult) { return b << mult; }

С остальным справится оптимизатор.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Задачка упрощена, конечно. Хотелось для конфигурации портов STM32L151 написать универсальное макро для всех регистров. А их там много. В некоторых для задания режима одного бита порта требуется один бит в регистре, в большинстве - 2, для альтернативных функций - 4. Думаю, как бы по имени регистра задать нужное количество сдвигов.

Может, и зря. Хочу понять, можно ли. Надо попробовать решение MrYuran.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Надо попробовать решение MrYuran.

Это не моё, а Аскольда Волкова :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это не моё, а Аскольда Волкова :)

Скорее уж K&R, а Аскольд Волков смог "осилить" :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Есть ли возможность в 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;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

#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)
...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А как вам такое решение.

Там, примеры для AVR приведены, но в архиве есть демо для STM32.

Изменено пользователем neiver

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А как вам такое решение

Не хватило усердия разобраться. Зато узнал много нового.

Судя по комментариям, все слишком сложно.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот какую... какое... "сочинил":

/* Биты конфигурации портов (* - после сброса) */
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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...