# AVR GCC - Any comfortable way of controlling single IO pins ?

#### ItsMike

##### New Member
Hey everyone.

I'm looking for a macro/function with no (or minimal) performance loss to control single IO pins using this syntax:

Writing:

PB0=<value>;
Where value can be anything, any value not 0 would be regarded as 1 (logic high).

Reading:

<variable>=PB0;

Last edited:

#### Sceadwian

##### Banned
Such functions already exist within C, for both read and write. If you need anything within a few cycles of the chip speed for importance you can't use C, you'd have to use ASM.

#### 3v0

##### Coop Build Coordinator
Forum Supporter
You can have some fun with this.

Compilers should know how to use bit set, clear, and test instructions. But having any non zero value as one prevents the use of bit test.

For fun compile this code and see which line results in the fewest instructions by looking at the ASM listing generated.

Code:
  char a;
PB0 = !!a; // first logical not converts to inverted bool, second un-inverts the value
PB0 = ~!a; // first logical not converts to inverted bool, bit not un-inverts
PB0 = a>0;
All 3 lines should give the same result but the compiler is free to figure out how. Be sure to try it with optimization too.

#### wkrug

##### Active Member
In Code Vision you can do this by PORTB.0=1; // Will set the first Pin of PORTB
If that should effect at GCC you should try yourself.

#### Exo

##### Active Member
Code:
//Macro's
#define SetPin(Port, Bit)    Port |= (1 << Bit)
#define ClearPin(Port, Bit)    Port &= ~(1 << Bit)

//Allows you to do the following in code...
SetPin(PORTB, PB3);   //Sets bit 3 on port B
ClearPin(PORTA, PA1);  //Clears bit 1 on port A
Accessing a single bit as a complete variable (as in PB0 = 0 for example) is not possible in true C. It's an extra gimmick added to some compilers but avr-gcc follows the true C standard so the above method is the only option. It does end up as sbi, cbi instructions tough, the compiler is smart enough for that.

In order to set the pin on any nonzero value , and clear it when zero do the following:
Code:
if (Value)
SetPin(PORTA, PA1);
else
ClearPin(PORTA, PA1);
If you need to use this a lot, you can put the whole thing in a macro like this:
Code:
#define PinVal(Port, Bit, Val)    Port = Val ? Port | (1 << Bit) : Port & ~(1 << Bit);

//Allows you to do the following in code
PinVal(PORTB, PB3, Value); //Will set bit 3 on port B if Value is nonzero, clear otherwise.

Last edited:

#### ItsMike

##### New Member
This is what i'm using right now, too bad I can't access a single bit as a complete variable.

#### External Solutions

##### New Member
These are my macros:

Code:
#ifndef cb
#define cb(reg, bit)    reg &= ~(1<<bit) //clear bit
#endif

#ifndef sb
#define sb(reg, bit)    reg |= (1<<bit) //set bit
#endif

#ifndef rb
#define rb(reg, bit)    (reg & (1<<bit)) //read bit
#endif
and examples of use:

Code:
int main(void)
{
sb(DDRB, 0); //port b 0 as output for led

while(1)
{
if( rb(PIND, 2) )
{
sb(PORTB, 0); //led on
}
else
{
cb(PORTB, 0); //led off
}
}
}

Loading