【问题标题】:Advanced Preprocesor Tokenization in CC 中的高级预处理器标记化
【发布时间】:2011-04-16 16:40:21
【问题描述】:

我在为我的 PIC 构建 C 宏时遇到问题。其他基于 C 的系统也是如此,因此也非常欢迎非 PIC C 专家。

假设我已经定义了我的 LED_1 引脚:

#define LED_1 A1    //A1 as output for LED_1

所以如果我想点亮一个 LED,我会写:

PORTAbits.RA1 = 1;

如果我想使用我的 LED_1 定义来实现,我必须再添加两个宏:

#define change_PORT_(var) PORTAbits.R##var
#define change_PORT(var) change_PORT_(var

并使用它:

change_PORT(LED_1) = 1;

它就像一个魅力。但问题是在上面的定义中我有

PORT A 位。##var

如果我想更改 PORTB 值怎么办?我必须为端口 A 和 B 构建单独的宏。但它甚至不是一个强大的解决方案。 我想出了一个想法,但我不知道为什么,它不起作用。

#define LED_1 A1
#define LED_2 B1

#define __A1 A   //This would be defined for all PORTA's pins such as A2,A3,A4 etc
#define __B1 B

#define ___change_PORT(var,var2)    PORT##var2 bits.R##var
#define __change_PORT(var,var2)   ___change_PORT(var,var2)
#define _change_PORT(var)    __change_PORT(var,__##var) // creating e.g. __A1
#define change_PORT(var)   _change_PORT(var)

当我尝试运行它时:

change_PORT(LED_1);

编译器将 __##var 更改为 ___A1 但它永远不会将 __A1 更改为 A 所以这个 MACRO没有按预期工作。

我花了很多时间试图修复它,所以我很感激任何帮助:)


编辑::


我可能已经找到解决问题的方法:
(LAT 只是另一个寄存器名称,但它的作用与 PORT 相同,因此此名称更改无关紧要)

#define ___PORTchange(var,var2) PORT##var2##bits.R##var
#define __PORTchange(var,var2)  ___PORTchange(var,var2)
#define CHANGE_TO_PORT_NAME(var) ___##var
#define _PORTchange(var)    __PORTchange(var,CHANGE_TO_PORT_NAME(var))
#define PORTchange(var) _PORTchange(var)

但我得到一个编译器错误:

100: PORTAbits.RA0 = 1;
^ (374) 缺少基本类型; int 假定(警告)
^ (983) 存储类重新声明
^ (984) 类型重新声明
^ (239) 重新定义标识符“PORTAbits”(从第 3900 行开始)
^ (314) “;”预计

所以没有它确实可以正确替换它,但我收到一个编译器警告,告诉我我重新定义了我无法理解的 PORTAbits。我只是想让预处理器将 PORTchange(var) 更改为 PORTxbits.Rvar,其中 x 是 A 或 B。但似乎我正在重新声明一些东西。

我不明白。

【问题讨论】:

  • 你能给出一个最小但完整的代码吗? (并说明您期望/想要什么以及您得到什么。)
  • 我在编辑标记后更改了代码。我现在的问题是为什么我的宏不只是用另一个文本替换一个文本,而是尝试重新定义一些预定义的结构(PORTAbits)。
  • 从您引用的错误来看,使用上下文很重要。
  • 感谢您的评论。确实,上下文很重要;)我的帖子中编辑后的代码版本似乎运行良好。我使用高科技 C 编译器,所以如果有人碰巧遇到类似的问题,我想这将是一个解决方案。 @AProgrammer 非常感谢您的帮助 :)
  • 哎呀,我以为我有答案了 - 暂时以为是 atmel,而不是 PIC。我删除了我的帖子。

标签: c macros token c-preprocessor pic


【解决方案1】:

如果我预处理(尝试了几个 gcc 版本和 sun cc)

#define LED_1 A1
#define LED_2 B1

#define __A1 AX
#define __B1 BX

#define ___change_PORT(var,var2)    PORT##var2##bits.R##var
#define __change_PORT(var,var2)   ___change_PORT(var,var2)
#define _change_PORT(var)    __change_PORT(var,__##var)
#define change_PORT(var)   _change_PORT(var)

change_PORT(LED_1);
change_PORT(LED_2);

我明白了

PORTAXbits.RA1;
PORTBXbits.RB1;

这显然是你想要的。你的编译器有错误吗?

【讨论】:

  • 我找到了部分解决方案并编辑了我的帖子。 @AProgrammer 你能说出现在的问题吗?或者更好的解决方案是什么;)
猜你喜欢
  • 2014-04-17
  • 1970-01-01
  • 1970-01-01
  • 2010-12-18
  • 2015-10-21
  • 1970-01-01
  • 1970-01-01
  • 2023-01-17
相关资源
最近更新 更多