avr-gcc-list
[Top][All Lists]
Advanced

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

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


From: E. Weddington
Subject: Re: [avr-gcc-list] efficiency of assigning bits
Date: Fri, 18 Mar 2005 09:59:30 -0700
User-agent: Mozilla Thunderbird 0.7.3 (Windows/20040803)

Royce & Sharal Pereira wrote:


So would it be a good idea (for saving uC time) to convert that above line to this:

PORTD = (PORTD & (unsigned char)~(_BV(0))) | (unsigned char)_BV(1)|_BV(2)|_BV(3));


Whew! What a long winded way to do things! This takes less time/energy to enter:

PORTD &= ~(1 | (1<<1) | (1<<2));

1. What you wrote above is different than what I wrote above. Follow the parentheses carefully to understand why.

And is quite readable.

2. In your opinion. Others may differ. In fact it is not always clear which bits are getting set or why. If you use symbolic names in place of the bit numbers, then it stands a better chance of being mnemonic. I prefer not having "magic numbers" in the source code.

For example, can you tell me offhand what this does on a mega128 without looking at the datasheet?

TIMSK |= (1<<5);

No?

However if you write it like this:

TIMSK |= _BV(TICIE1);

Then you can at least make out that this is setting the Timer 1 Input Capture Interrupt Enable bit which enables that interrupt.

When you are using symbolic names you have the opportunity to not be tied to a particular implementation. What this means is that if that particular bit changed position, then you wouldn't have to change all these hardcoded numbers all over your code. You just change the definition of the symbol. This method works very well in your own application where you can provide application specific symbols, such as:

#define STATUS_LED    3
//......
PORTA |= _BV(STATUS_LED);

What if the above code was for a prototype board, which then needed to be re-layed out? What if the status LED needed to move to a different pin? Then all you have to do is to change the definition, in one place only; the code stays the same.


It also has the same effect as the (unsigned char)  attribute above.


3. IIRC, a constant defaults to an *integer*, which on the AVR is 16 bits. It does not default to an unsigned char. So you still have the same problem and you will still have to typecast the constants.

Eric




reply via email to

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