用于定义符号的C宏

时间:2012-02-05 01:40:41

标签: c macros

我正在使用带有ANSI C(gcc;而不是C ++)的微控制器,并且需要定义许多硬件引脚。我正在寻找一种方法来使引脚定义更具可读性。

我想我想要一个允许我在一行中定义每个引脚的宏,如下所示:

PIN(LED_RED, E, 2);  
PIN(LED_YELLOW, B, 3);  
PIN(LED_GREEN, A, 4);  

(这只是一个简单的例子 - 我要定义几十个引脚)。 现在我看起来像这样丑陋的代码:

#define LED_RED           (LATEbits.LATE2)  
#define LED_RED_TRIS      (TRISEbits.TRISE2)  

#define LED_YELLOW        (LATBbits.LATB3)   
#define LED_YELLOW_TRIS   (TRISBbits.TRISB3)    

#define LED_GREEN         (LATAbits.LATA4)    
#define LED_GREEN_TRIS    (TRISAbits.TRISA4)   

每个引脚有2个符号;一个用于读/写引脚,另一个用于设置I / O方向(_TRIS定义)。锁存器和TRIS定义来自MCU供应商提供的头库;避免使用它们并不实际。

我很确定可以在C中编写一个定义两个符号的宏,但我对#和##的东西不是很好。这是我半生不熟的尝试(不起作用):

#define _PIN( id,port,pos) #define ##id (LAT ##port ##bits.LAT ##port ##pos )  
#define _TRIS(id,port,pos) #define ##id _TRIS (TRIS ##port ##bits .TRIS ##port ##pos )  
#define PIN(  id,port,pos) _PIN(id,port,pos)  _TRIS(id,port,pos)

有办法做到这一点吗?

或者,是否有其他方法来简化我的引脚定义?我想把它归结为一行/引脚,并摆脱我所拥有的端口ID(A,B,C等)和位数(2,3,4等)的重复现在;把它们放两次只是在找麻烦。

干杯,

- 戴夫

1 个答案:

答案 0 :(得分:4)

您无法在宏中定义宏,但您可以执行其他一些技巧。

这是“相当难看的宏观”领域。

#define MY_CAT(x, y) x ## y
#define MY_CAT2(x, y) MY_CAT(x, y)
#define LED(x) (MY_CAT2(MY_CAT2(LAT, PORT_ ## x), bits) \
                .MY_CAT2(LAT, MY_CAT2(PORT_ ## x, POS_ ## x)))

#define PORT_RED E
#define POS_RED 2
#define PORT_YELLOW B
#define POS_YELLOW 3
#define PORT_GREEN A
#define POS_GREEN 4

LED(RED)
LED(YELLOW)
LED(GREEN)

扩展(使用gcc -E检查)是:

(LATEbits .LATE2)
(LATBbits .LATB3)
(LATAbits .LATA4)

仅仅因为宏是你的锤子并不意味着这是一个钉子。尝试使用Python或其他东西生成源代码,更好。

LEDS = [
    ('RED', 'E2'),
    ('YELLOW', 'B3'),
    ('GREEN', 'A4'),
]
for name, pos in LEDS:
    print '#define LED_%s (LAT%sbits.LAT%s)' % (name, pos[0], pos)
    print '#define LED_%s_TRIS (TRIS%sbits.TRIS%s)' % (name, pos[0], pos)

输出结果为:

#define LED_RED (LATEbits.LATE2)
#define LED_RED_TRIS (TRISEbits.TRISE2)
#define LED_YELLOW (LATBbits.LATB3)
#define LED_YELLOW_TRIS (TRISBbits.TRISB3)
#define LED_GREEN (LATAbits.LATA4)
#define LED_GREEN_TRIS (TRISAbits.TRISA4)

然后你继续检查脚本及其输出到你的修订控制系统。

附录:我不打算解释宏技巧是如何运作的,因为我不想很好地学习这个技巧来解释它。