我正在使用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中是这样。有一些解决方法,但我正在寻找一个干净的解决方案。它存在吗?
答案 0 :(得分:0)
我不确定你会考虑什么"清洁"解决方案,但这对我有用,并且看起来不太糟糕:
/* target header */
#define RCC_CFGR_PLLMULL 0x003C
#define RCC_CFGR_PLLMULL1 0x0003
/* pasting macros */
#define APPEND_VAL_HELPER(A, B) A ## B
#define APPEND_VAL(A, B) APPEND_VAL_HELPER(A, B)
#define RCC_CFGR(T, N) APPEND_VAL(RCC_CFGR_, APPEND_VAL(T, N))
您可以将其用作例如
#define FOO RCC_CFGR(PLLMUL, 1)
您也可以
#define BAR RCC_CFGR(PLLMUL, )
将BAR
定义为RCC_CFGR_PLLMUL
(无尾)。
显然,这是特定于可能的目标宏的一个子集,但它完成工作并干净地读取。据我所知,没有办法编写一个完全通用的令牌粘贴宏 - 那些最常见的宏会遇到诸如你描述的问题之类的问题。