| Author |
Message |
|
|
Posted: Mar 05, 2008 - 04:08 AM |
|


Joined: Mar 28, 2001
Posts: 20374
Location: Sydney, Australia (Gum trees, Koalas and Kangaroos, No Edelweiss)
|
|
Am I correct that it is a lot about nothing?? ie it can be safely discarded and use the usual 1<<bitname.
The example
Code:
TCCR2 = _BV(COM20)|_BV(CTC2)|_BV(CS20);
DDRD = _BV(PD7);
Can also be
Code:
TCCR2 = (1<<COM20)|(1<<CTC2)|(1<<CS20);
DDRD = (1<<PD7);
of course this would also apply to the various incantations of defining a bit like portx.x and therefore make code a bit more ahemmm portable...
And finally, is this just a winAvr thingy or a GCC thingy? ie all micro flavours of GCC use _BV |
_________________ John Samperi
Ampertronics Pty. Ltd.
www.ampertronics.com.au
* Electronic Design * Custom Products * Contract Assembly
|
| |
|
|
|
|
|
Posted: Mar 05, 2008 - 04:12 AM |
|

Joined: Apr 01, 2004
Posts: 3812
Location: New Mexico
|
|
| Hi John, as far as I'm aware, _BV is only defined in the avr-libc headers. Extracted from avr/sfr_defs.h in avr-libc:
Code:
#define _BV(bit) (1 << (bit))
Personally, I don't use _BV(bit) since it does save any characters over (1<<bit), adds a layer of indirection, and is not cross-platform compatible (without redefining _BV on non-avr-libc platforms). |
_________________ Kevin Rosenberg
http://b9.com
http://kevin.hypershots.com
|
| |
|
|
|
|
|
Posted: Mar 05, 2008 - 04:24 AM |
|

Joined: Jan 20, 2008
Posts: 210
Location: Canada
|
|
| I always wish there was a way to define a macro with a variable length parameter list. For example, it would be nice if you could do something like this:
Code:
TCCR2 = _BV(COM20,CTC2,CS20);
DDRD = _BV(PD7);
|
|
|
| |
|
|
|
|
|
Posted: Mar 05, 2008 - 04:53 AM |
|


Joined: May 30, 2004
Posts: 8118
Location: Cincinnati, Ohio
|
|
|
kmr wrote:
...adds a layer of indirection, and is not cross-platform compatible (without redefining _BV on non-avr-libc platforms).
You mean more like... adds a layer of obscurity.
Well, exactly how does _bv(x); work?
Does:
_bv(0); // Set bit low?
and:
_bv(1); // Set bit high?
If so, then I can see a text reduction.
But if not, I'm willing to bet that, under the mask, _bv(x); is no different then #define SET_BIT(x) (1<<x);, or simply PORTX |= (1<<x);, and the like.
I can't say, as I use one of the underdog compilers and there is no such thing as _bv(x);.
This this is a question I've always wanted to know the answer to, but was afraid to ask... |
_________________ Carl W. Livingston, KC5OTL
microcarl@roadrunner.com
"There are only two ways to sleep well at night... be ignorant or be prepared."
The original Dragon Slayer !
Long live the AVR!!!
|
| |
|
|
|
|
|
Posted: Mar 05, 2008 - 05:00 AM |
|


Joined: Mar 28, 2001
Posts: 20374
Location: Sydney, Australia (Gum trees, Koalas and Kangaroos, No Edelweiss)
|
|
|
Quote:
but was afraid to ask...
That's why I'm here for. Keep on pm-ming silly questions and I'll ask them in your behalf. I won't tell anyone.  |
_________________ John Samperi
Ampertronics Pty. Ltd.
www.ampertronics.com.au
* Electronic Design * Custom Products * Contract Assembly
|
| |
|
|
|
|
|
Posted: Mar 05, 2008 - 05:32 AM |
|


Joined: Nov 06, 2007
Posts: 181
Location: Austin, TX
|
|
|
kmr wrote:
Hi John, as far as I'm aware, _BV is only defined in the avr-libc headers. Extracted from avr/sfr_defs.h in avr-libc:
Code:
#define _BV(bit) (1 << (bit))
Personally, I don't use _BV(bit) since it does save any characters over (1<<bit), adds a layer of indirection, and is not cross-platform compatible (without redefining _BV on non-avr-libc platforms).
I think this discussion is making it more obscure than it needs to be. _BV is a C macro, pure and simple, and is of course an acronym for BitValue. It could have been an inline function and no-one would know the difference. I guess one person's "layer of indirection" is another person's "encapsulation of function".
I personally find _BV easier to read than (1 << bit) but I guess it is ultimately down to personal choice. |
_________________ --Mike
|
| |
|
|
|
|
|
Posted: Mar 05, 2008 - 05:56 AM |
|

Joined: Apr 01, 2004
Posts: 3812
Location: New Mexico
|
|
|
microcarl wrote:
If so, then I can see a text reduction.
Carl: I meant text reduction in terms of horizontal space. For example, "_BV(5)" is the same number of characters as "(1<<5)".
Mike: Yes, _BV(bv) is more mnemonic than (1<<bv), but for someone doing development on multiple compilers and multiple platforms, then it is essential to ensure that _BV(bv) is defined and in-line with expectaions on that platform. For myself, it's easier and more rapid to know the (1<<bv) idiom than ensure there is some _BV() preprocessor macro or inline function already defined before employing that expansion. |
_________________ Kevin Rosenberg
http://b9.com
http://kevin.hypershots.com
|
| |
|
|
|
|
|
Posted: Mar 05, 2008 - 06:14 AM |
|


Joined: May 30, 2004
Posts: 8118
Location: Cincinnati, Ohio
|
|
|
kmr wrote:
microcarl wrote:
If so, then I can see a text reduction.
Carl: I meant text reduction in terms of horizontal space. For example, "_BV(5)" is the same number of characters as "(1<<5)".
Yes, I understood that.  |
_________________ Carl W. Livingston, KC5OTL
microcarl@roadrunner.com
"There are only two ways to sleep well at night... be ignorant or be prepared."
The original Dragon Slayer !
Long live the AVR!!!
|
| |
|
|
|
|
|
Posted: Mar 05, 2008 - 06:23 AM |
|

Joined: Apr 01, 2004
Posts: 3812
Location: New Mexico
|
|
|
microcarl wrote:
Yes, I understood that.
Heh, I should have assumed!
I see your point more clearly now: what the heck does _BV() mean? Gotta check the preceding header files to find out! |
_________________ Kevin Rosenberg
http://b9.com
http://kevin.hypershots.com
|
| |
|
|
|
|
|
Posted: Mar 05, 2008 - 08:27 AM |
|


Joined: May 07, 2007
Posts: 291
Location: Seattle
|
|
When I'm deep into coding, I usually start thinking macros like _BV make the code easier to read. Primarily because they reduce symbol characters (one reason I've always disliked perl is its heavy use of symbols).
But then I do something else for a while, and when I return to the code I think: "What do all these macros do again?" Maybe I should create wordy macros like
Code:
#define _TWOTOTHEPOWEROF(bit) (1 << (bit))
Argg... then I'll need editor macros to reduce typing. Just can't win  |
|
|
| |
|
|
|
|
|
Posted: Mar 05, 2008 - 10:13 AM |
|


Joined: Mar 01, 2001
Posts: 4953
Location: Rocky Mountains
|
|
It's not a WinAVR thing, and not a GCC thing, it is an avr-libc thing.
It is not meant to add a layer of obscurity. Believe it or not, there are people out there who know nothing about bit-wise operators, and so this was created as a "convenience macro" for these people. It is convenient to use because it is slightly shorter, and it hides the use of the bit-wise left-shift operator for those people (typically coming from a PC environment) who are uncomfortable with these operators.
BTW, BV stands for Bit Value.
Feel free to use it, or not, as you like. |
|
|
| |
|
|
|
|
|
Posted: Mar 05, 2008 - 10:49 PM |
|


Joined: Mar 28, 2001
Posts: 20374
Location: Sydney, Australia (Gum trees, Koalas and Kangaroos, No Edelweiss)
|
|
|
Quote:
Feel free to use it, or not, as you like.
GREAT. 1 less thing to understand...now let's see what else I don't need to know about C  |
_________________ John Samperi
Ampertronics Pty. Ltd.
www.ampertronics.com.au
* Electronic Design * Custom Products * Contract Assembly
|
| |
|
|
|
|
|
Posted: Mar 06, 2008 - 08:50 AM |
|

Joined: Jan 16, 2006
Posts: 211
Location: leeds
|
|
Much ado about nothing...
_BV() and several other macros are purely shorthand notation for "common" operations. Some have suggested that _BV(x) is easier to understand than (1<<x) but I think that can't be the case as you'd have to know that BV stood for bit value and that in turn meant two to the power of the value supplied. In which case knowing that 1<<x does the same thing isn't exactly a massive jump.
In fact, to my mind, the use of _BV(x) adds more of a mystery for the beginner... what s this magic thing, why does it start with an underscore, why is it in capitals, etc?
In my opinion the name is terse and adds no understanding whatsoever (it doesn't, for example, indicate why you'd want to perform this magic in the first place - usually to produce a "mask value"). So I'll go further, and suggest that its purpose is to OBSCURE, allowing us who are in the know look superior  |
|
|
| |
|
|
|
|
|
Posted: Mar 06, 2008 - 10:58 AM |
|


Joined: Aug 22, 2004
Posts: 1624
Location: Germany
|
|
|
Quote:
I always wish there was a way to define a macro with a variable length parameter list.
You might don't get a variable parameter list but you could use something like this:
Code:
// BM => Bit Mask
#define _BM(bit7, bit6, bit5, bit4, bit3, bit2, bit1, bit0) \
( \
((bit7 == 7) << (bit7 & 7)) | \
((bit6 == 6) << (bit6 & 6)) | \
((bit5 == 5) << (bit5 & 5)) | \
((bit4 == 4) << (bit4 & 4)) | \
((bit3 == 3) << (bit3 & 3)) | \
((bit2 == 2) << (bit2 & 2)) | \
((bit1 == 1) << (bit1 & 1)) | \
((bit0 == 0) << (bit0 & 0)) \
)
You could use the macro this way (invert bit numbers which should be cleared):
Code:
UCSR0A = _BM (RXC0, TXC0, ~UDRE0, ~FE0, ~DOR0, ~UPE0, ~U2X0, ~MPCM0);
Which would be preprocessed to:
Code:
(*(volatile uint8_t *)(0xC0)) = ( ((7 == 7) << (7 & 7)) | ((6 == 6) << (6 & 6)) | ((~5 == 5) << (~5 & 5)) | ((~4 == 4) << (~4 & 4)) | ((~3 == 3) << (~3 & 3)) | ((~2 == 2) << (~2 & 2)) | ((~1 == 1) << (~1 & 1)) | ((~0 == 0) << (~0 & 0)) );
and compiled to:
Code:
ldi r24, 0xC0 ; 192
sts 0x00C0, r24
Regards
Sebastian |
|
|
| |
|
|
|
|
|
Posted: Mar 06, 2008 - 11:11 AM |
|


Joined: Aug 22, 2004
Posts: 1624
Location: Germany
|
|
|
Code:
UCSR0A = _BM (RXC0, TXC0, !UDRE0, !FE0, !DOR0, !UPE0, !U2X0, !MPCM0);
Gives the same result. The NOT operator might be the clearer method in this matter.
Regards
Sebastian |
|
|
| |
|
|
|
|
|
Posted: Mar 06, 2008 - 06:17 PM |
|

Joined: Oct 29, 2006
Posts: 2651
|
|
|
schickb wrote:
When I'm deep into coding, I usually start thinking macros like _BV make the code easier to read. Primarily because they reduce symbol characters (one reason I've always disliked perl is its heavy use of symbols).
But then I do something else for a while, and when I return to the code I think: "What do all these macros do again?" Maybe I should create wordy macros like
Code:
#define _TWOTOTHEPOWEROF(bit) (1 << (bit))
Argg... then I'll need editor macros to reduce typing. Just can't win
Much of my source is python code that generates header files.
If FRED is supposed to refer to pin D4, the python would generate
Code:
#define PORT_FRED PORTD
#define PIN_FRED PIND
#define DDR_FRED DDRD
#define BIT_FRED 4
#define MASK_FRED 0x10
#define PCINT_FRED_vect PCMSK2
This way, I only have to use FRED==D4 once.
The rest of the time, I just have to spell correctly.
If I don't, I'll get an error message. |
_________________ Michael Hennebry
Iluvatar is the better part of Valar.
|
| |
|
|
|
|
|
Posted: Mar 06, 2008 - 06:31 PM |
|

Joined: Nov 17, 2004
Posts: 13844
Location: Vancouver, BC
|
|
|
Quote:
It is convenient to use because it is slightly shorter
Hmmm...
Code:
_BV(n)
(1<<n)
Looks like the same length to me. |
_________________ Regards,
Steve A.
The Board helps those that help themselves.
|
| |
|
|
|
|
|
Posted: Mar 06, 2008 - 07:57 PM |
|

Joined: Oct 29, 2006
Posts: 2651
|
|
|
Koshchi wrote:
Quote:
It is convenient to use because it is slightly shorter
Hmmm...
Code:
_BV(n)
(1<<n)
Looks like the same length to me.
The former has fewer shift changes. |
_________________ Michael Hennebry
Iluvatar is the better part of Valar.
|
| |
|
|
|
|
|
Posted: Mar 06, 2008 - 10:08 PM |
|


Joined: Mar 28, 2001
Posts: 20374
Location: Sydney, Australia (Gum trees, Koalas and Kangaroos, No Edelweiss)
|
|
|
|
|
|
|
Posted: Mar 06, 2008 - 10:12 PM |
|

Joined: Nov 17, 2004
Posts: 13844
Location: Vancouver, BC
|
|
|
Quote:
The former has fewer shift changes.
But that doesn't make it "shorter". |
_________________ Regards,
Steve A.
The Board helps those that help themselves.
|
| |
|
|
|
|
|