My first tutorial:
A philosophy of mine for programming is eliminating repeated code as much as possible. Because of this I've always been "annoyed" at code like this for use in generalized functions:
// Defines like this #define LED_PORT PORTB #define LED_DDR DDRB #define LED_PIN PINB #define LED_BIT 1 // To make this code more general LED_DDR |= 1<<LED_BIT; // Set output LED_PORT |= 1<<LED_BIT; // Turn on LED_PIN |= 1<<LED_BIT; // Toggle
This may not look repetitive, but I wanted to make it look like this using a macro:
#define LED_PORT B #define LED_PIN 1 DDR(LED_PORT) |= 1<<LED_PIN; PORT(LED_PORT) |= 1<<LED_PIN; PIN(LED_PORT) |= 1<<LED_PIN;
This simplifies the defines that need to be adjusted for different boards but makes the actual code a little different.
If anyone else has tried to do this, the knee-jerk is to use these macros:
#define PORT(port) PORT ## port #define DDR(port) DDR ## port #define PIN(port) PIN ## port
Unfortunately, this does not work. You get errors saying something to the effect of PORTLED_PORT undefined that will force most to give up and use the standard of a separate define for PORT, DDR, and PIN. What happens is the compiler actually appends the literal LED_PORT to PORT instead of taking the value we defined LED_PORT to be.
Fortunately, there is a workaround for this. You just need an extra macro step:
#define PORT_(port) PORT ## port #define DDR_(port) DDR ## port #define PIN_(port) PIN ## port #define PORT(port) PORT_(port) #define DDR(port) DDR_(port) #define PIN(port) PIN_(port)
I hope someone likes & uses this!