c - 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。
- 我对这些值进行预处理的方法是否正确?
- 为此目的编写宏的正确方法是什么?
我正在使用 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
变量的值时,宏会自动改变它的值。
推荐阅读
- afnetworking - AFNetworking 3.0 下载后台模式
- angular - Firebase 存储安全规则 400 错误问题“权限被拒绝。无法访问存储桶...”(在部署时,在本地主机上工作时)
- authentication - 如何为 IdentityServer url 的登录链接生成重定向 url:https://localhost:5000/Account/Login?ReturnUrl=
- javascript - 在 laravel 5.3 的文件夹中上传文件时出现问题?
- javascript - 如何通过 JavaScript 连接到 MS-SQL 数据库?
- linux - 使用 CURL 抓取图像?
- c# - 如何将 C# Web API BasicAuthentication 与 IIS 集成?
- c# - Hangfire 排队错过的时间表
- mysql - Symfony2 在 Symfony 和 csv 文件中添加查询日志
- postgresql - 如何在尝试启动 pgsql 容器时修复“无法启动服务 pgsql:b'OCI 运行时创建失败:”?