[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] efficiency of assigning bits

From: Dave Hansen
Subject: Re: [avr-gcc-list] efficiency of assigning bits
Date: Mon, 21 Mar 2005 19:19:50 -0500

From: "David Brown" <address@hidden>
[... I wrote...]]
> I know the preprocessor is somewhat out of style these days, but consider
> the scheme I use:
> // LED example
> // These macros (except IO_LED) are the ones to appear in in functions
> //
> #define IO_LED        A,3                 // Port letter and bit number
> #define Led_On() Reset_Output(IO_LED) // inverted logic, just for fun
> #define Led_Off()   Set_Output(IO_LED)
> #define Is_Led_On() (!Get_Output(IO_LED))
<aol> Me too! </aol>

Tying the port along with the bit number is a huge step up from just
defining a name for a bit number.


I use a similar setup, although I seldom go as far as to make a set of
macros for each individual output (Led_On(), etc.).  I'm quite happy to
write Reset_Output(IO_LED) in my main code. The macros I use are a bit more

I do that because of the somewhat, uh, fluid nature of development around here. It's nothing to change an output from high side to low side driven, tie the function of one I/O to another, change the meaning of an input, whatever. Which is why I used the inverted LED output in my example: the code says "do this," i.e. "Led_On()," and the macros hide the details (like whether that means driving the output high or low). And when something does change, I only have to fix it in one spot.

And for those that use simpler setups (they are still useful), why this
obsession with using bit numbers rather than masks?  Rather than writing
    #define STATUS_LED 3
    PORTA |= (1 << STATUS_LED);

just write
    #define STATUS_LED (1 << 3)

Guessing here...

I think bit numbers are used for "hysterical" reasons (AIUI, the original sbi and cbi macros expanded inline assembly, and those instructions require the bit number).

Also, the I/O header files provided by gcc give bit numbers rather than masks for things like GICR, ADCSRA, etc. I believe the extraction of these bit numbers could be automated from the electronic datasheets for the chips (though I'm not sure it's actually done that way).

All in all, it's probably better to be consistent and always use bit numbers rather than some masks and some numbers.

Macros (and constants, and inline functions) are there to improve
readability, and save repetative typing.  Since it's the mask you use, not
the bit number, put the mask in the definition.

Don't forget maintenance (which I mentioned above, though not by name).

So I'd go a step further and suggest hiding I/O behind macros even for simple setups:

#define Status_Led_On() (PORTA |= (1<<3))
#define Status_Led_Off() (PORTA &= ~(1<<3))

That way if the status LED moves or changes polarity, there's only one place you have to go to fix it.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]