首页 > 解决方案 > C 预处理器宏

问题描述

问题:

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

在代码中,有一个 CLCD_ROWS 和 CLCD_COLS 的定义,它们对应于 Active 显示尺寸。

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

并且有各种液晶显示器的定义。例如,如果我们连接了 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);

这给了我一个“缺少;”的错误。

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

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

我正在使用 C99 编译器。

标签: cmacrosc-preprocessorc99

解决方案


首先,您使用函数类型宏的方法是错误的。即使您修复了您遇到的错误,宏也不会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变量的值时,宏会自动改变它的值。


推荐阅读