C macro to define characters

I work with a microcontroller with ANSI C (gcc; not C ++) and has a lot of hardware pins to determine. I'm looking for a way to make the broods more understandable.

I think I need a macro that allows me to define each output on a single line, for example:

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

(this is just a simple example - I have dozens of contacts to identify). Right now I have an ugly code:

 #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) 

Each pin has 2 characters; one for reading / writing pins, and the other for setting the I / O direction (_TRIS definition). Latch and TRIS definitions are from the header library provided by the MCU; It is not very practical not to use them.

I'm sure you can write a macro in C that will define both characters, but I'm not very good at # and ##. Here is my half-baked attempt (not working):

 #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) 

Is there any way to do this?

Or is there another way to simplify my contact definitions? I would like to get it down to one line / output and get rid of duplicating the port identifier (A, B, C, etc.) And the number of bits (2,3,4, etc.) that I have Now; introducing them twice, just asks for trouble.

Greetings

- Dave

+4
source share
1 answer

You cannot define macros in macros, but you can do some other tricks.

It is located on the territory of a "rather ugly macro."

 #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) 

Extension (check with gcc -E ):

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

Just because macros are your hammer, this does not mean that it is a nail. Try to create source code with Python or something else, much more pleasant.

 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) 

Output:

 #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) 

Then you just go ahead and check both the script and its output in your version control system.

Addendum: I will not explain how the macro trick works, because I do not want to understand the trick well to explain this.

+4
source

Source: https://habr.com/ru/post/1394820/


All Articles