1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

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

Discussion in 'AVR' started by ItsMike, Sep 2, 2011.

  1. ItsMike

    ItsMike New Member

    Joined:
    Mar 3, 2011
    Messages:
    108
    Likes:
    3
    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: Sep 2, 2011
  2. Sceadwian

    Sceadwian Banned

    Joined:
    Oct 27, 2006
    Messages:
    14,047
    Likes:
    141
    Location:
    Rochester, US
    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.
     
  3. 3v0

    3v0 Coop Build Coordinator Forum Supporter

    Joined:
    Jul 14, 2006
    Messages:
    9,404
    Likes:
    227
    Location:
    OKLAHOMA USA
    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 (text):
      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.
     
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. wkrug

    wkrug Active Member

    Joined:
    May 30, 2010
    Messages:
    271
    Likes:
    29
    Location:
    Germany

    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.
     
  6. Exo

    Exo Active Member

    Joined:
    Sep 18, 2003
    Messages:
    1,953
    Likes:
    1
    Location:
    Belgium
    Code (text):

    //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 (text):

    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 (text):

    #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: Sep 7, 2011
  7. ItsMike

    ItsMike New Member

    Joined:
    Mar 3, 2011
    Messages:
    108
    Likes:
    3
    This is what i'm using right now, too bad I can't access a single bit as a complete variable.
     
  8. External Solutions

    External Solutions New Member

    Joined:
    May 4, 2014
    Messages:
    1
    Likes:
    0
    These are my macros:

    Code (text):
    #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 (text):
    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
            }
        }
    }
     
  9. misterT

    misterT Well-Known Member Most Helpful Member

    Joined:
    Apr 19, 2010
    Messages:
    2,697
    Likes:
    368
    Location:
    Finland

Share This Page