| Author |
Message |
|
|
Posted: Jul 18, 2011 - 06:06 PM |
|

Joined: Aug 26, 2008
Posts: 27
Location: Arkansas
|
|
In the bit manipulation macros of the orignal post:
#define bit_get(p,m) ((p) & (m))
#define bit_set(p,m) ((p) |= (m))
#define bit_clear(p,m) ((p) &= ~(m))
... etc., should the & in the first one be &= ? Would it make any difference? |
|
|
| |
|
|
|
|
|
Posted: Jul 18, 2011 - 08:55 PM |
|


Joined: Jul 18, 2005
Posts: 62354
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
No,
But the fact that it's not obvious kind of proves how pointless these kind of macros are in aiding readability. Think about:
Code:
bit_set(foo, 0x20);
bit_clear(foo, 0x08);
if (bit_set(foo,0x80)) {
which really says (without all the parenthesis):
Code:
foo |= 0x20;
foo &= ~0x08;
if (foo & 0x80) {
As you can see you don't want an '=' in the last one as it's used in a different context to the other two. The confusion here is that then macro names are so similar you might think they'd all be used in the same context.
Stay clear of macros - you know it makes sense! |
_________________
|
| |
|
|
|
|
|
Posted: Jul 18, 2011 - 09:07 PM |
|

Joined: Nov 17, 2004
Posts: 13851
Location: Vancouver, BC
|
|
|
Code:
if (bit_set(foo,0x80))
You mean "bit_get" don't you? |
_________________ Regards,
Steve A.
The Board helps those that help themselves.
|
| |
|
|
|
|
|
Posted: Jul 19, 2011 - 12:13 AM |
|

Joined: Aug 26, 2008
Posts: 27
Location: Arkansas
|
|
OK, I see it now. It was just my poor reading. Or poor reading glasses.
But I do like these macros. I agree I should make sure I understand how they work, but think they can prevent careless errors if I understand their proper use.
Nick |
|
|
| |
|
|
|
|
|
Posted: Sep 13, 2011 - 08:47 PM |
|


Joined: Jun 01, 2011
Posts: 38
Location: Waterloo, Ontario, Canada
|
|
In regard to a problem I just had could some one explain to me the reason this doesn't work properly (it affects all the bits)
Code:
PORTD &= (0<<D_I);
And this one does work properly?
Code:
PORTD &= ~(1<<D_I);
|
|
|
| |
|
|
|
|
|
Posted: Sep 13, 2011 - 09:12 PM |
|


Joined: Nov 17, 2004
Posts: 6137
Location: Great Smokey Mountains.
|
|
They would both work just fine as written.
Did you read the tutorial?
What do you mean by properly?
Smiley |
_________________ FREE TUTORIAL: 'Quick Start Guide for Using the WinAVR C Compiler with ATMEL's AVR Butterfly' AVAILABLE AT: http://www.smileymicros.com
|
| |
|
|
|
|
|
Posted: Sep 13, 2011 - 09:25 PM |
|

Joined: Nov 17, 2004
Posts: 13851
Location: Vancouver, BC
|
|
|
Quote:
They would both work just fine as written.
No they wouldn't. The first clears all bits of PORTD.
Quote:
I just had could some one explain to me the reason this doesn't work properly
Break it down: 0<<D_I means that you are shifting the number 0 by some number of bits (whatever number D_I is). Shifting 0 by anything will always result in 0. You then AND that with PORTD. ANDing anything with 0 will always result in 0.
Quote:
And this one does work properly?
Again, break it down. 1<<D_I will shift the number 1 by D_I bits. If D_I is 2, that makes the result 4 (so in binary you went from 0b00000001 to 0b00000100). You then invert that (the ~), which in binary gives you 0b11111011. You then AND that with PORTD. |
_________________ Regards,
Steve A.
The Board helps those that help themselves.
|
| |
|
|
|
|
|
Posted: Sep 14, 2011 - 02:02 AM |
|


Joined: Jan 23, 2004
Posts: 9832
Location: Trondheim, Norway
|
|
|
Quote:
They would both work just fine as written.
ಠ_ಠ
- Dean  |
_________________ Atmel Studio 6.1 is now released, grab it here.
Report AS6/ASF bugs here.
|
| |
|
|
|
|
|
Posted: Sep 14, 2011 - 04:47 AM |
|


Joined: Nov 17, 2004
Posts: 6137
Location: Great Smokey Mountains.
|
|
|
Koshchi wrote:
Quote:
They would both work just fine as written.
No they wouldn't. The first clears all bits of PORTD.
Which is a perfectly valid use for that notation so I repeat: 'They would both work just fine as written'. I'd never use the first notation, but who am I to say someone shouldn't use a valid C notation? In fact I've seen (0<<XXX) used in the Atmel Butterfly code, so somebody somewhere must think is okay to do this.
Now if you want to make assumptions about the intent which is unstated, then maybe they don't do what the poster wants them to do, but is that for us to decide or should he tell us what he is trying to do?
Smiley |
_________________ FREE TUTORIAL: 'Quick Start Guide for Using the WinAVR C Compiler with ATMEL's AVR Butterfly' AVAILABLE AT: http://www.smileymicros.com
|
| |
|
|
|
|
|
Posted: Sep 14, 2011 - 08:30 AM |
|


Joined: Mar 27, 2002
Posts: 18585
Location: Lund, Sweden
|
|
|
Quote:
In fact I've seen (0<<XXX) used in the Atmel Butterfly code, so somebody somewhere must think is okay to do this.
Perhaps, but most likely not in a statement lacking ~ and using &= . Discussing if (0<<XXX) is meaningful or clarifying must be done in the context of the complete statement.
E.g. you might very well do
Code:
someRegister = (1<<someBitNumber) | (0<<anotherBitNumber);
to make it clear that you relly want anotherBit to be clear. Not that the code actually (0<<anotherBitNumber) has the exact effect to actually clears that bit, but you are doing some documentation of intent in the code. |
|
|
| |
|
|
|
|
|
Posted: Sep 14, 2011 - 09:13 AM |
|


Joined: Jul 18, 2005
Posts: 62354
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
|
Quote:
In fact I've seen (0<<XXX) used in the Atmel Butterfly code, so somebody somewhere must think is okay to do this.
No, no , no. The only use of a 0<< is when you want to document the fact that something is deliberately not being set. maybe something like:
Code:
TCCRB = (1 << CS02) | (0 << CS01) | (1 << CS00);
Too often we see threads here where the user has grasped the fact that to set a bit they use:
Code:
SFR |= (1 << bit);
but then see variants of:
Code:
SFR |= (0 << bit);
SFR &= (0 << bit);
SFR &= ~(0 << bit);
where they believe that using 0 in the mask is the way to switch things off. As we all know, it isn't.
This notion should be stomped on from a great height before it confuses more beginners (especially in this thread we all point them towards to learn this stuff!).
The only use of (0 << foo) is to document that foo is not being used. |
_________________
|
| |
|
|
|
|
|
Posted: Sep 14, 2011 - 09:37 AM |
|


Joined: Mar 27, 2002
Posts: 18585
Location: Lund, Sweden
|
|
|
Quote:
As we all know
Exchange "some" for "all" and we're closer to the actual situation. |
|
|
| |
|
|
|
|
|
Posted: Sep 14, 2011 - 03:22 PM |
|


Joined: Jun 01, 2011
Posts: 38
Location: Waterloo, Ontario, Canada
|
|
Hey Guys, Thanks for all your input but I believe Koshchi nailed what I was looking for, and smiley was just being ragging on me for not stating my intent explicitly.
Either way Cheers! |
|
|
| |
|
|
|
|
|
Posted: Sep 14, 2011 - 04:34 PM |
|


Joined: Nov 17, 2004
Posts: 6137
Location: Great Smokey Mountains.
|
|
|
clawson wrote:
Quote:
In fact I've seen (0<<XXX) used in the Atmel Butterfly code, so somebody somewhere must think is okay to do this.
No, no , no. The only use of a 0<< is when you want to document the fact that something is deliberately not being set. maybe something like:
Code:
TCCRB = (1 << CS02) | (0 << CS01) | (1 << CS00);
Too often we see threads here where the user has grasped the fact that to set a bit they use:
Code:
SFR |= (1 << bit);
but then see variants of:
Code:
SFR |= (0 << bit);
SFR &= (0 << bit);
SFR &= ~(0 << bit);
where they believe that using 0 in the mask is the way to switch things off. As we all know, it isn't.
This notion should be stomped on from a great height before it confuses more beginners (especially in this thread we all point them towards to learn this stuff!).
The only use of (0 << foo) is to document that foo is not being used.
Cliff - It was late and my thought was 'jeez this guy didn't even glance at the tutorial' since all it would have taken was a glance to answer his question. Usually I just pass on by but for some reason this one exceeded a threshold, thus my response which the poster sees correctly as me ragging on him. And as usual, your response fully explains why his first usage doesn't make sense and the real 'proper' use of (0<<xxx).
Smiley |
_________________ FREE TUTORIAL: 'Quick Start Guide for Using the WinAVR C Compiler with ATMEL's AVR Butterfly' AVAILABLE AT: http://www.smileymicros.com
|
| |
|
|
|
|
|
Posted: Oct 14, 2011 - 01:46 PM |
|

Joined: Oct 12, 2011
Posts: 1
|
|
|
robinsm wrote:
Quote:
BenG wrote:
As an additional item to check if a bit is clear:
Code:
if(~(foo) & 0x80)
{
}
My 1st choice would be for the following which, IMHO, is easier to "read":
Code:
if ( ( foo & 0x80 ) == 0 )
{
...
}
should result in the same compiler generated code.
Don
and another way...
Code:
if (!( foo & 0x80 ))
{
...
}
 |
|
|
| |
|
|
|
|
|
Posted: Dec 19, 2011 - 06:30 PM |
|

Joined: Dec 09, 2010
Posts: 153
|
|
now wait a moment if the compiler knows a bit's name as variable then why it hasn ot been writen like this:
while (CS10==0); |
|
|
| |
|
|
|
|
|
Posted: Dec 19, 2011 - 06:35 PM |
|


Joined: Jul 18, 2005
Posts: 62354
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
Do not cross post and do not post to tutorials except to suggest improvements to the original article.
The last 202,030 people who have read this thread clearly understood the reason. If you don't I can only suggest you re-read until you understand. Also see the point I just made regarding bit number vs. bit mask in your cross-post. |
_________________
|
| |
|
|
|
|
|
Posted: Dec 30, 2011 - 09:42 PM |
|

Joined: Dec 30, 2011
Posts: 4
|
|
how to manipulate each bit of a unsigned char variable doing something like that?
#define bit0 variable_unsigned_char
#define bit1 variable_unsigned_char
#define bit2 variable_unsigned_char
#define bit3 variable_unsigned_char
#define bit4 variable_unsigned_char
#define bit5 variable_unsigned_char
#define bit6 variable_unsigned_char
#define bit7 variable_unsigned_char
//in code do something like that
bit0 = 1;
bit3 = 0;
?????????????????? |
|
|
| |
|
|
|
|
|
Posted: Dec 30, 2011 - 10:06 PM |
|


Joined: Jul 18, 2005
Posts: 62354
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
|
|
|
|
|
Posted: Dec 31, 2011 - 01:37 AM |
|

Joined: Dec 30, 2011
Posts: 4
|
|
I'm trying to do something like this.
//*************************************
ram far unsigned char RAM_used[5];
#define p0 RAM_used[0]
#define p1 RAM_used[1]
#define p2 RAM_used[2]
#define p3 RAM_used[3]
#define p4 RAM_used[4]
//than I'm trying to control every bit of p0,p1,p2,p3,p4
struct _8bits
{
unsigned bit0:1;
unsigned bit1:1;
unsigned bit2:1;
unsigned bit3:1;
unsigned bit4:1;
unsigned bit5:1;
unsigned bit6:1;
unsigned bit7:1;
}
#define p0_b0 p0.bit0
#define p0_b1 p0.bit1
...
matriz
-----> byte
-----------> bit
//for when I do something like this
p0_b0 = 1;
// bit p0_b0 = 1
// byte p0 = 0x01
// RAM_used[0] = 0x01
//because, sometimes I will modify a single bit, sometimes the entire byte and the entire RAM too.
//for writing the EEPROM, I used a pointer to RAM_used;
//for some situations I move some value to the byte
//and for rapidly actions I set the bit
//I'm having some troubles... everything that I try generate a error....
HELP! |
|
|
| |
|
|
|
|
|