0

我正在使用 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. 至少在 GCC 中,我无法弄清楚如何在B不扩展的情况下进行扩展。A有解决方法,但我正在寻找一个干净的解决方案。它存在吗?

4

1 回答 1

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, )

定义BARRCC_CFGR_PLLMUL(无尾)。

显然,这是特定于可能的目标宏的一个子集,但它可以完成工作并且读取干净。据我所知,没有办法编写一个完全通用的标记粘贴宏——那些最通用的宏会遇到您所描述的问题。

于 2014-08-25T20:00:06.293 回答