Я работаю с микроконтроллером STM32F1, для которого предоставляется заголовок, определяющий битовые маски и значения для регистров следующим образом:
#define RCC_CFGR_PLLMULL //Mask of PLL multiplier setting bits
#define RCC_CFGR_PLLMULL1 //Value of PLL multiplier bits for PLL x1
#define RCC_CFGR_PLLMULL2 //Value of PLL multiplier bits for PLL x2
#define RCC_CFGR_PLLMULL3 //Value of PLL multiplier bits for PLL x3
и т.д.
Что я хочу сделать, так это определить мой множитель PLL как целое число, чтобы я мог использовать его для получения значения часов, т.е. PLLCLK = IN_CLK * PLL_MULT
, и вставить значение в RCC_CFGR_PLLMULL
, чтобы получить правильные биты настройки. Макросы, которые я обычно использую для этого, следующие:
#define APPEND_VAL_HELPER(A, B) A##B
#define APPEND_VAL(A, B) APPEND_VAL_HELPER(A,B)
Затем, если я определю SOME_NUM как, скажем, 123:
#define FOO APPEND_VAL(BAR, SOME_NUM)
В результате FOO
определяется как BAR123
. Обычно это работает. Вот в чем проблема: в этом случае RCC_CFGR_PLLMULL
является допустимым токеном перед вставкой. Это приводит к тому, что он расширяется при вызове APPEND_VAL
, и я получаю что-то вроде ((uint32_t)0x003C0000)123
. Я не могу понять, как заставить B
расширяться без расширения A
, по крайней мере, в GCC. Есть обходные пути, но я ищу чистое решение. Он существует?