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 » need help with bit shift in Temperature Sensor project

February 09, 2010
by kloog
kloog's Avatar

I understand the concept of bit shifts on bytes of data, but I'm confused by the math in function adc_init (first project)

(1<<ADEN) ADEN represents the 7th bit in ADCRSA Doesn't the right side of the operator need to be at least a byte? Could someone explain how we get 10000000 by the expression (1<<ADEN)

February 09, 2010
by N3Roaster
N3Roaster's Avatar

1 is 00000001.

<< 7

shifts the bits 7 to the left. Thus,

1 << 7

is 10000000. Note the 1 is 7 places farther to the left.

1 << 0

would leave the 1 in the same place. If you're placing the result in an 8 bit value, you'll typically only see left shifts from 0 (which does nothing and is hopefully optimized away by the compiler) to 7, as anything else would push the right most bit out and all you'd be left with is 0. If I'm remembering correctly, the compiler gives a warning if it looks like a shift does that. This sort of bit shift is really common for setting individual bits in control registers and you'll see this a lot in later projects.

Now, there is another use of bit shifts in that project to take 8 bit chunks of data and shift them to the appropriate bytes of a larger value, in this case moving the high byte from the ADC to the right place in a 16 bit type. I had to do this on the project I'm working on now which involves a 24 bit ADC (read in 8 bit chunks over SPI). In these cases, you'll typically see shifts that are multiples of 8.

February 09, 2010
by Rick_S
Rick_S's Avatar

If you look in the iom168p.h include file you'll see that ADEN is defined as 7

#define ADCSRA _SFR_MEM8(0x7A)
#define ADPS0 0
#define ADPS1 1
#define ADPS2 2
#define ADIE 3
#define ADIF 4
#define ADATE 5
#define ADSC 6
#define ADEN 7

So when you see

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

You could substitute ADEN with a 7, ADPS2 with a 2, ADPS1 with a 1, and ADPS0 with a 0. Thus setting bit 0,1,2, and 7 of ADCSRA.

If you want to see the list of all the pre-defined register names, just look in the file I listed at the top.

HTH,

Rick

February 09, 2010
by Phrank916
Phrank916's Avatar

The key to understanding this cocept is to remember this statement from the NerdKit Guide:

"ADMUX, ADCSRA, ADEN and all the rest of the variables used are predefined in on[sic] the include files."

So, ADEN is really a variable that is defined in the myriad include files that we reference at the top of the code. I was actually able to dig it out of io8535.h under the \WinAVR-20090313\avr\include\avr\ directory. In there it defines ADEN as bit 7. So the actual statement would be (1<<7) meaning shift a 1 to the left 7 bits. Thus 10000000 (Remember we start out on the 0 bit.)

Hope that clears it up.

Ted

February 09, 2010
by Phrank916
Phrank916's Avatar

heheh, we all answered at basically the same time. Also, I guess those variables are defined in more than one file ;-P

February 09, 2010
by kloog
kloog's Avatar

Thanks to all for the timely help! I probably should have noticed that it is 1 (in binary) that is shifted, and not the variable! Also thanks for the tips on the header files.

May 06, 2010
by avicell
avicell's Avatar

Instead of ORing ADCSRA per the NK code, would setting ADCSRA = 135; achieve the same result?

May 06, 2010
by hevans
(NerdKits Staff)

hevans's Avatar

Hi avicell,

Yep. You got it right. The shifts are just a fancy way of building the number 135 which eventually gets set into the register. Building the number the way we do it in the guide results in much more readable code as you can see exactly which bits are being set and look at the datasheet to see how the module will behave. If you wrote 135 not only would anyone who looks at your code have to start doing binary math every time, but I bet you a week from now when you came back to look at your code you would be confused by it too!

Humberto

Post a Reply

Please log in to post a reply.

Did you know that the printf format string "%.3f" will show three digits after the decimal point? Learn more...