I/O Ports (Part 4)

Part 12345

Well, sometimes, it feel like my all life will not suffice to learn all this C stuff.
After experimenting quite complex programming trics in order to make the ports manipulation more parametric, I found one of these magic syntaxes: the “##” so as to say the concatenation, or “the” glue command!

Say that you would like to set any pin from any port, or control the direction of any pin from any port. Here is the quick and dirty solution:

void setup(void) 
{
	/* Input pin */
	pinMode(2, INPUT); 
	/* Bias pin */
	digitalWrite(2, HIGH);
	/* Output pin */
	pinMode(A5, OUTPUT); 
	/* Clear pin */
	digitalWrite(A5, LOW);
};

void loop(void) 
{
	/* Sense input pin */
	if (digitalRead(2) == HIGH) {
		digitalWrite(A5, HIGH);		
	}
	else {
		digitalWrite(A5, LOW);
	}
	delay(100);
};

Here is the fast mode solution:

void setup(void) 
{
	/* Input pin */
	DDRD &= ~(0x01 << 2);
	/* Bias pin */
	PORTD |= (0x01 << 2);
	/* Output pin */
	DDRC |= (0x01 << 5);
	/* Clear pin */
	PORTC &= ~(0x01 << 5);
};

void loop(void) 
{
	/* Sense input pin */
	if (((PIND >> 2) & 0x01) == 0x01) {
		PORTC |= (0x01 << 5);		
	}
	else {
		PORTC &= ~(0x01 << 5);	
	}
	delay(100);
};

Unless you pass the reference to the port as an adress, there is a simple alternative:

The glue function!

Ahem, nope, not this one! This other one down there:

/* Define the glue macro */
#define GLUE(a, b) a##b 
/* Ports macros */
#define SET(port, p, m) GLUE(port, p) |= (1 << m) 
#define CLR(port, p, m) GLUE(port, p) &= ~(1 << m) 
#define TGL(port, p, m) GLUE(port, p) ^= (1 << m) 
#define GET(port, p, m) ((GLUE(port, p) >> m) & 0x01)

void setup(void) 
{
	/* Input pin */
	CLR(DDR, D, 2); 
	/* Bias pin */
	SET(PORT, D, 2); 
	/* Output pin */
	SET(DDR, C, 5); 
	/* Clear pin */	
	CLR(PORT, C, 5);
};

void loop(void) 
{
	/* Sense input pin */
	if (GET(PIN, D, 2) == 0x01) {
		SET(PORT, C, 5);		
	}
	else {
		CLR(PORT, C, 5);		
	}
	delay(100);
};

Next post on same subject

Leave a Reply

You must be logged in to post a comment.