C中的高级预处理器标记化

时间:2011-04-16 16:40:21

标签: c macros token c-preprocessor pic

我在为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值怎么办?我将不得不为PORT 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)缺少基本类型;假设(警告)
               ^(983)存储类重新声明
               ^(984)类型redeclared
               ^(239)重新定义标识符“PORTAbits”(来自第3900行)
               ^(314)“;”预期

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

我不明白。

1 个答案:

答案 0 :(得分:2)

如果我预处理(尝试使用几个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;

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