NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » questions about setting bits

May 25, 2011
by s0nee
s0nee's Avatar

Hi, I am new to electronics and I have a question about the code that set the bits in the tempsensor project in the guide.

   ADCSRA |= (1<<ADSC);

What does " |= " mean ? I have never seen this before. What does " << " do ? I googled and found out that it was "bit shift" ? How can you set the ADSC bit to 1 with that ?

In the extra practice part AND and OR, there is a question like this :

   11011010 | (1<<2) = 11011110

Again, what is (1<<2) ? I understand AND and OR, but "<<" ? There is no explanation in the guide.

Thanks! You guys rock!

May 26, 2011
by Ralphxyz
Ralphxyz's Avatar

Hi s0nee, I asked this same question about a year ago.

So consider this a test of my learning.

  1. "What does " |= " mean ?

Would you know what ADCSRA += 1 means?

These are "Compound assignment operators".

Here is the Wikipedia link for Augmented assignment (or compound assignment).

So with ADCSRA += 1 you would have:

 ADCSRA = ADCSRA + 1

and therefore ADCSRA |= 1 would be :

ADCSRA = ADCSRA | 1

Instead of ADDing itself plus one you are ORing itself with one.


Now << left shifting

11011010 | (1<<2) = 11011110

You do understand the OR operation correct .

lets start with 1<<2

We want to left sift the first bit 2 places to the left

So we have :

   1

left shifted two places:

100

And then we OR it with 11011010

     100                 
11011010
---------
11011110

God I can not believe I just did that, well I know I will corrected if I am wrong.

I hope this helps.

Ralph

May 26, 2011
by s0nee
s0nee's Avatar

Hi Ralph,

Thank you for the answer. I understand it now. That helps me a lot :)

Have a nice day!

May 26, 2011
by s0nee
s0nee's Avatar

By the way, I have another question. Here is a part of the tempsensor code :

 // read from ADC, waiting for conversion to finish
 // (assumes someone else asked for a conversion.)
 // wait for it to be cleared
 while(ADCSRA & (1<<ADSC)) {
   // do nothing... just hold your breath.
 }

ADCSRA is a 8-bit register. So when the MCU checks the condition

 (ADCSRA & (1<<ADSC))

the condition will return a 8-bit binary number instead of a 1-bit like 1-true or 0-false ?

Thanks a bunch!

May 26, 2011
by Noter
Noter's Avatar

Any non-zero value is true so it does return true or false as you suspect. However, I think for a logical operation like this the true return value is -1 but it doesn't matter so much as long as it is not zero.

May 26, 2011
by Noter
Noter's Avatar

The smallest addressable unit is a byte so even a single bit will always reside somewhere in an 8 bit byte. To mask a particular bit(s) in the byte you use the logical and &, to set a specific bits you use logical or |. But the whole byte is always present in any operation. Even the I/O pins are bits in the I/O register which is a byte.

May 26, 2011
by s0nee
s0nee's Avatar

Noter, you said :

 Any non-zero value is true so it does return true or false as you suspect.

Before the while loop, ADCSRA is set to 10000111

 ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);

If the ADSC bit is 0, then ADCSRA is 10000111

If the ADSC bit is 1, then ADCSRA is 11000111

In both cases ADCSRA is non-zero, so the condition always evaluates to true ?

My question is, how do you/the MCU/the program check the ADSC bit if it is 1 or 0 with that statement ?

 (ADCSRA & (1<<ADSC))
May 26, 2011
by Noter
Noter's Avatar

Yes, it always evaluates to true if non-zero.

The | and & are bitwise operators. Earlier I said they are logical but they're not, they are bitwise which means they operate on a bit by bit basis. The logical operators are || and && and return either true or false.

Using the bitwise or, 1 or anything is 1, it takes two 0's to give a 0. Using the bitwise and, 0 and anything is 0, it takes two 1's to give a 1.

The value of (1<<ADSC) is (0b00000001 << 6) which is 0b01000000. Since only one bit is set then only that one corresponding bit in ADCSRA (bit 6) will give us a non-zero result because we are using an bitwise & (and).

Take a look at the Wikipedia Bitwise operation doc which I'm sure explains it better than I can.

May 26, 2011
by 6ofhalfdozen
6ofhalfdozen's Avatar

Hiya s0nee,

When you say "(ADSCRA & (1<<ADSC))" you are "AND"-ing ADSCRA with (1<<ADSC). My bit shifting skills stink (so I might be a bit off), but what I believe (1<<ADSC) means is 1 shifted to the position ADSC holds. For example, if ADSC is the third bit in a byte, (1<<ADSC) really means 00000100 . So if you "AND" anything with 00000100 the ONLY time you will get a response of not zero is if and only if the corresponding position has a one. So assume "x" can be either 0 or 1, if ADSCRA is xxxxx0xx, you will get a zero, but if ADSRCA is xxxxx1xx you will get a 1 for my example here. Basically, its the way to check a bit hidden in a byte without too much mcu overhead. Hopefully that helps some.

May 26, 2011
by s0nee
s0nee's Avatar

Ok I understand it now.

if ADCSRA is x1xxxxxx then (ADCSRA & (1<<ADSC)) is actually

 x1xxxxxx AND
 01000000
 --------
 01000000

which is true.

if ADCSRA is x0xxxxxx then

 x0xxxxxx AND
 01000000
 --------
 00000000

which is false.

Thank you guys so much!

P.S. : 6ofhalfdozen : ADSC is actually bit 6 if you number the bits from 0 to 7, left to right (page 257 of the datasheet)

May 26, 2011
by 6ofhalfdozen
6ofhalfdozen's Avatar

Hiya s0nee,

I kinda figured it was something like that, but I left my datasheet at home and felt like using 3. just one of those "3" kinda days. Anyhow, as long as you got the lightbulb on, its all good.

Post a Reply

Please log in to post a reply.

Did you know that microcontrollers have two different kinds of memory, program space (flash) and SRAM? Learn more...