C 预处理器宏

C preprocessor macro

问题:

我正在为微控制器项目中的 LCD 编写通用 C 库。 最多可以添加 8 个不同地址的不同尺寸(例如 128*96 或 64*48)的 LCD(例如 LCD3 和 LCD7)。但一次只有其中一个被主动编码。所以我想到了一种机制。

代码中有CLCD_ROWS和CLCD_COLS的定义,对应Active display size

#define CLCD_ROWS   // Active LCD rows
#define CLCD_COLS   // Active LCD columns

还有各种 LCD 的定义。例如,如果我们连接了 LCD3 和 LCD7,我们定义它们的大小:

#define CLCD_ROWS3  96
#define CLCD_COLS3  64

#define CLCD_ROWS7  128
#define CLCD_COLS7  32

问题:

我写了一个[错误的]宏来重新定义CLCD_ROWS和CLCD_COLS的值:

#define cLcd_setActiveI2CcLcd(X)    \
CLCD_ROWS = CLCD_ROWS##X            \
CLCD_COLS = CLCD_COLS##X

在我的主要代码中调用宏:

cLcd_setActiveI2CcLcd(7);

这给了我 "missing ;" 的错误。

用变量很容易实现。但由于这些值是硬编码的,我认为它们是 "preprocessable" 因为在低端 MCU 中需要每一位 RAM。

  1. 我对这些值进行预处理的方法是否正确?
  2. 为此目的编写宏的正确方法是什么?

我使用的是 C99 编译器。

首先,你使用函数型宏的方法是错误的。即使您修复了错误,宏也不会 CLCD_ROWS 等于 CLCD_ROWS7,而是 CLCD_ROWSX(这就是宏的工作方式,它连接您提供的东西,而不是它的东西价值)。相反,如果您想使用宏来减少 RAM 使用,您可以将代码更改为:

第一个解决方案

#define ROW_COLS 7 // change this if you use different display

#if ROW_COLS == 7

#define CLCD_ROWS  128
#define CLCD_COLS  32

#elif ROW_COLS == 3

#define CLCD_ROWS  96
#define CLCD_COLS  64

#endif

第二个解决方案 如果你想在运行时动态改变你的显示尺寸,你可以这样做:

static int display_cnt;

#define CLCD_ROWS ((display_cnt == 3) ? 96 : 128)
#define CLCD_COLS ((display_cnt == 3) ? 64 : 32)

所以当你改变display_cnt变量的值时,宏会自动改变它的值。