ViKo 1 21 марта, 2012 Опубликовано 21 марта, 2012 · Жалоба Есть ли возможность в C сделать что-то подобное: #define TEST(A,B,MULT) \ A = B<<(#if (#MULT == "ONE") 1 \ #elif (#MULT == "TWO") 2); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 27 21 марта, 2012 Опубликовано 21 марта, 2012 · Жалоба Есть ли возможность в 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) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 141 21 марта, 2012 Опубликовано 21 марта, 2012 · Жалоба Вроде бы нет. Задача не до конца понятна, возможно тут нужен не препроцессор? typedef enum { ZERO, ONE, TWO } mult_t; inline int TEST(int b, mult_t mult) { return b << mult; } С остальным справится оптимизатор. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DogPawlowa 0 21 марта, 2012 Опубликовано 21 марта, 2012 · Жалоба Есть ли возможность в C pragma inline дает вполне стабильные результаты. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 21 марта, 2012 Опубликовано 21 марта, 2012 · Жалоба Задачка упрощена, конечно. Хотелось для конфигурации портов STM32L151 написать универсальное макро для всех регистров. А их там много. В некоторых для задания режима одного бита порта требуется один бит в регистре, в большинстве - 2, для альтернативных функций - 4. Думаю, как бы по имени регистра задать нужное количество сдвигов. Может, и зря. Хочу понять, можно ли. Надо попробовать решение MrYuran. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 27 21 марта, 2012 Опубликовано 21 марта, 2012 · Жалоба Надо попробовать решение MrYuran. Это не моё, а Аскольда Волкова :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 21 марта, 2012 Опубликовано 21 марта, 2012 · Жалоба Это не моё, а Аскольда Волкова :) Скорее уж K&R, а Аскольд Волков смог "осилить" :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sasamy 0 21 марта, 2012 Опубликовано 21 марта, 2012 · Жалоба Есть ли возможность в 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 1 21 марта, 2012 Опубликовано 21 марта, 2012 · Жалоба #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 0 21 марта, 2012 Опубликовано 21 марта, 2012 (изменено) · Жалоба А как вам такое решение. Там, примеры для AVR приведены, но в архиве есть демо для STM32. Изменено 21 марта, 2012 пользователем neiver Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 21 марта, 2012 Опубликовано 21 марта, 2012 · Жалоба А как вам такое решение Не хватило усердия разобраться. Зато узнал много нового. Судя по комментариям, все слишком сложно. В библиотеке Std_Periph_Lib тоже куча функций используется, структуры для инициализации... якобы, с целью упрощения. Только ну его в болото, такое упрощение. Когда вместо изучения битов в регистрах приходится лазить по исходникам библиотеки, а потом все равно лезть за битами в дейташит. Не говоря уже о том ужасном количестве кода, во что превращается инициализация порта, в частности. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 22 марта, 2012 Опубликовано 22 марта, 2012 · Жалоба Вот какую... какое... "сочинил": /* Биты конфигурации портов (* - после сброса) */ 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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться