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 » Analog to Digital Conversion

April 23, 2012
by jlaskowski
jlaskowski's Avatar

I don't quite understand how to interpret the digital value returned from the analog-to-digital conversion. I understand it's a number from 0 to 1023, and I sense that what it actually means is dependent upon the reference voltage, but I don't know the relationship exactly. Would someone please explain the relationships? Does it only return voltages between 0 and the reference voltage?

April 23, 2012
by Ralphxyz
Ralphxyz's Avatar

For a reference using the Nerdkit Temp Sensor project connect PC0 to GND(-) what do you get?

Then connect PC0 to VCC(+) now what do you have?

So now you see the full range of ADC values.

You can also use a potentiometer with the wiper to PC0 to see varying readouts proportional to wiper voltage.

Then best to spend some time with the mcu specsheet in the ADC Section 23.

23. Analog-to-Digital Converter 
23.1 Features 
• 10-bit Resolution     
• 0.5 LSB Integral Non-linearity 
• ± 2 LSB Absolute Accuracy 
• 13 - 260 μs Conversion Time 
• Up to 76.9 kSPS (Up to 15 kSPS at Maximum Resolution) 
• 6 Multiplexed Single Ended Input Channels 
• 2 Additional Multiplexed Single Ended Input Channels (TQFP and QFN/MLF Package only) 
• Temperature Sensor Input Channel 
• Optional Left Adjustment for ADC Result Readout 
• 0 - VCC ADC Input Voltage Range 
• Selectable 1.1V ADC Reference Voltage 
• Free Running or Single Conversion Mode 
• Interrupt on ADC Conversion Complete 
• Sleep Mode Noise Canceler

Ralph

April 23, 2012
by jlaskowski
jlaskowski's Avatar

So, it can't convert voltages less than 0 or greater than VCC?

April 23, 2012
by Ralphxyz
Ralphxyz's Avatar

correct, well the reference voltage might not be 5 volts. I am not sure if it may be > 5 volts I'll have to check the specsheet.

I am sure it can be < 5 volts.

Ralph

April 23, 2012
by jlaskowski
jlaskowski's Avatar

In case someone else was looking for a simple explanation of the relationship between the input voltage, reference voltage, and digital value produced by the converter, I found this statement in the article, ABCs of ADCs:

An ADC has an analog reference voltage or current against which the analog input is compared. The digital output word tells us what fraction of the reference voltage or current is the input voltage or current. So, basically, the ADC is a divider.

So, input_voltage = (conversion_result / max_conversion_values)) * reference_voltage. In the Atmel chip that comes with the USB Nerdkit, the result comes in 10 bits, so the max_conversion_values is 1024.

April 23, 2012
by jlaskowski
jlaskowski's Avatar

Thanks, that's good to know, Ralph. In that case, I won't expect to use it to test the 120V AC from the outlet (without seriously stepping down the voltage)!

April 23, 2012
by Ralphxyz
Ralphxyz's Avatar

I do not believe you can use AC.

Ralph

April 24, 2012
by Tyron
Tyron's Avatar

Ralhxyz,

Not to change the subject, even though I am in the first few program blocks regarding the ADC for the Temperature Sensor project. Quick-fast curiosities that I need explained; in the first program block-page 50, there are two OR symbols "|", one following the "//" in the second comment line. The other is in the last command line of the first program block, ADCSRA |= (1<<ADSC). Moreover, there is also another (ADCSRA |= (1<<ADSC)) at the end of the second program block--page 51. The last thing I wish exprained is the, correct my nomenclature if needed, "typedef" ( _t ) following the function, uint16. I am trying to follow Nerdkit's admonition to back-ground study instead of just copy/paste-ing text.

Regards,

Tyron

April 24, 2012
by Ralphxyz
Ralphxyz's Avatar

Tyron, I do not understand your question.

Here is the first block of code please be more specific in exactly what you are asking.

// PIN DEFINITIONS:
//
// PC0 -- temperature sensor analog input

void adc_init() {
  // set analog to digital converter
  // for external reference (5v), single ended input ADC0
  ADMUX = 0;

  // set analog to digital converter
  // to be enabled, with a clock prescale of 1/128
  // so that the ADC clock runs at 115.2kHz.
  ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);

  // fire a conversion just to get the ADC warmed up
  ADCSRA |= (1<<ADSC);
}

Ralph

April 24, 2012
by 6ofhalfdozen
6ofhalfdozen's Avatar

Tyron,

I believe the first "or" you mention is the cursor in the screen cap the NK guys used for the manual. There is no reason to put an "or" there and it does look a little scrawny and offset for a true "or". So for the first, it is an oops and not a valid character.

As for the second, it makes the "=" become something else, a bitwise Or. If you read on in the manual, there is more mentioned about those in pages 57-63 and later on during the bitwise arithmetic project.

As for the "_t", no clue. never figured that one out...

April 24, 2012
by jlaskowski
jlaskowski's Avatar

Tyron,

Your first question is regarding this in the PDF:

// PIN DEFINITIONS:
//|
// PC0 -- temperature sensor analog input

The OR symbol after the comment in the second line is a typo, it is part of the comment and does nothing. Though shown in the PDF, it doesn't exist in the downloaded code.

The second OR symbol that you are asking about is in this line of code:

ADCSRA |= (1<<ADSC)

This is actually a special C-operator that does OR and assignment in one shorthand operator. Thus, it is equivalent to this:

ADCSRA = ADCSRA | (1<<ADSC)
April 24, 2012
by jlaskowski
jlaskowski's Avatar

As far as uint16_t, it is not a function, but a return type for the function and you'll see it used throughout the code. uint16_t is actually an alias for the type, "unsigned int." When you download the development environment and the sample code, the C header file, stdint.h, which is under avr/include/ (in the development environment installation directory, not the sample code directory) has the following line:

typedef unsigned int uint16_t;

This simply says that instead of typing "unsigned int" a lot through your code, you can shorthand it for uint16_t. The uint part tells you that it's an unsigned integer, the 16 tells you that the complier, when compiling for this chip, will make unsigned ints 16-bits. I believe the "_t" is a naming convention for "type". So, uint16_t is a 16-bit, unsigned integer type.

April 25, 2012
by Tyron
Tyron's Avatar

Thank You All,

I will look over, in depth, all your responses. I like what I see just skimming through it. You know , just blo'n off steam here, I got to say, the Blogisphere, what a rats nest. Unless you work in the bowels of Bell Labs or Motorola, how does anyone get a clear, non-conflicting answer from anybody. Is C programming actually C programming or what? Or does it change from day to day? Is it me, or is it a case of "more than one way to skin a cat"? Feel free to offer an "Intro to C" that is considered "good and applicable", by most of the programming community. I'm actually starting to fear my OWN questions.

Again, Thank You for your interest and support!!!!

Tyron

April 26, 2012
by hevans
(NerdKits Staff)

hevans's Avatar

Hi Tyron,

There are many beginners that get this same feeling of frustration when first starting out with hardware programming. I think most of the conflicting answers you get come not from the fact that C itself is evolving or changing from day to day, but from the fact that it is used to run so many different embedded devices out there and each of them interfaces in a slightly different way. There really isn't such a thing as "good and applicable" to all of embedded programming because that book would take several years to read. That is why our approach is to try and start you off with some of the basics and try to support you and our community as you explore other facets of embedded programming that you are interested in.

Keep on asking great questions, and most importantly don't give up!

Humberto

April 29, 2012
by Tyron
Tyron's Avatar

Hey Humberto,

What you say seems to be the only reasonable explanation. Since I'm at the terminal, let me ask a couple of questions. On page 51, regarding the "while loop" command line, two braces "{}" are containing a comment: // do nothing... just hold your breath. Are these braces "{}" there as part of the "subroutine" of the "while loop", or for some other reason? The other question is a little more involved. Back to page 50; specifically, the ADCSRA command line that ORs several bits of that register. Now in the center page explanation bubble, there is explained the need to create four individual binary numbers, and then OR-ing these four individual binary numbers that represent bits already in that particular register. Jumping to conclusions: Does this mean that the controller is assessing all seven bits of that register, first, before giving a "result" for that register? How should I interpret?

Spanx,

Tyron

April 30, 2012
by hevans
(NerdKits Staff)

hevans's Avatar

Hi Tyron,

The two braces are part of the syntax for the while loop. That is just how while loops are written.

while (some_condition_to_evaluate) {
  //code to execute
  //goes here
}

I don't really understand your second question. Perhaps you are getting confused about the use of ADEN,ADPS2, etc. On that line the only thing that is a real register on the chip is ADCSRA. We are setting the ADCSRA register to a number of our choosing. Depending on which bits of the ADCSRA register we set, the ADC will be have differently. The number we create on the right hand side of the equal sign is just a number, the ADEN,ADPS2 etc are just variables that stand for the bit positions of those particular bits.

Humberto

May 02, 2012
by Tyron
Tyron's Avatar

Thax Humberto,

That's what I thought regarding the "while loop". Just needed validation.
Regarding the rest: On the PDF instructions, page 50, the big dialogue balloon, center page, the discussion talks about needing to set ADCSRA register to "...equal 10000111 in binary.". The discussion eventually goes on to say, "What this line does is creates four separate numbers. (1<<ADEN) creates 10000000, (1<<ADPS2) creates 00000100," etc, etc. "Then we OR these numbers together to create the number we want. In C the | operator means OR.". So, looking at the code line, would not =(s) work, or &-ing these bits to set the register, work just as well? I am assuming the answer is no. So, why and what's the process behind why that code line is written the way it is? Does that help?

Thanks again,

Tyron

May 02, 2012
by pcbolt
pcbolt's Avatar

Tyron -

I know Humberto could answer this better than I could but if he doesn't get a chance to answer right away I can give it a shot. When you asked "would not =(s) work?", the answer is yes equals would work. We could set the register ADCSRA equal to 10000111 in a couple of different ways like...

ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);  // -or-
ADCSRA = 0b10000111; // -or-
ADCSRA = 0x87;       // -or-
ADCSRA = 135;        // all statements will do the same thing

So yes there are many ways to skin the ol' cat. But if you look at the 4 statements, the one that is most informative to what you are actually trying to accomplish is the first one. You can tell right away you set the enable ADC bit (ADEN), and the 3 "prescaler" bits (ADPS 2,1,0). When you're in the trenches writing code you may not care, but if you need to debug it months later you'll be glad to took the time to spell things out.

As far as using the AND statement, that won't work in this case. If you AND them all together you'll just get 00000000. Here's some things to keep in mind when dealing with bit-wise operators:

  • The minimum size of the variables is 8-bits
  • Each OR/AND operation works only between bits in the same place. For example, z = x|y will look at bit 7 of y and bit 7 of x, "OR" them and put the result in bit 7 of z. Same for bits 6, 5, 4 etc.
  • If x represents a 1 or a 0, x | 0 = x and x | 1 = 1; x & 0 = 0 and x & 1 = x;
  • Using this knowledge you can set and clear bits without even knowing what one of the variables is. Also, you can keep bits the same without knowing what they are.

I know it looks strange, but believe it or not these are actually shortcuts.

May 03, 2012
by Rick_S
Rick_S's Avatar

The reason to use the OR logic is to change only the registers (bits in the byte) we want to change without effecting the other bits in that byte. Using equality logic works fine as long as your goal is to set every bit to a certain state. For instance,

Lets say you want to use the Analog to digital coverter. The ADCSRA register is a prime example of where you probably would not want to use equality. The reason being, there are 8 bits in that register that effect the settings of the ADC. One of those bits (ADSC) actually starts a conversion.

If you look at the tempsensor project, you'll see a line that does the setup of the ADC

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

Then a couple of lines after you see this line:

ADCSRA |= (1<<ADSC);

So in the first line they use logical OR to "create" the Byte. They then assign that byte (with the equal sign) to ADSRA. Then however, a single bit in that byte needs toggled on to start a conversion. That is when using OR comes in handy. Because by OR'ing (1<<ADSC) (remember ADSC is equal to 6 as defined in the includes) you only turn on bit 6 in that byte leaving all the configuration bits alone.

Rick

May 03, 2012
by Tyron
Tyron's Avatar

Rock on fellas,

This is the kind of detail I'm looking for. I think I am what you call a "bottom-up" learner. So, it's hard for me to just do something, "because that's the way we do it". Only to be given the explanation a couple years later, like mathematics. And besides, what you've given me, I will have some homework to do-I like that. Someday, I'll get this temperature sensor running.

Again thanks for the quick responses,

Tyron

May 04, 2012
by Ralphxyz
Ralphxyz's Avatar

Tyron, just so you'll not feel alone, try searching the forum for ADCSRA this is probable one of the most common (repeated) questions here.

But it's good each time I read it it gets closer to actually sinking in.

Ralph

May 30, 2012
by Tyron
Tyron's Avatar

Hey Ralph,

I'm still working on the temp sensor programming. I checked the blogisphere regarding "The While Loop". I understand the protocol, while ( condition ){}, and as long as the condition remains true, the code block that follows,continues. I "read" the statement, "while(ADCSRA & (1<<ADSC))", as follows: "WHILE" the ADCSRA register is ONE--AND--ADSC is ONE(on), the conversion continues. The confusion is, if we're to put the "operand" ADCSRA in the condition without its own operator, unlike 1<<ADSC. Does the C protocol for while loops let us assume ADCSRA is ONE? Moreover, why could we not write (1<<ADSC) as (1=ASDC)? In this statment, how would you explain "<<"?

Let me refine my question(s): CONNOTATIVELY, how would you describe, or state, this condition to the layperson? As a programmer, how would you deduce to state it this way?

REGARDS,

Tyron

May 30, 2012
by Ralphxyz
Ralphxyz's Avatar

The confusion is, if we're to put the "operand" ADCSRA

Ok, here is a test "what the heck does 1<<ADSC mean or do"?

Hint:

ADCSRA is a register not an operand (of course my recollection of operand is rather rusty).

Ralph

May 30, 2012
by pcbolt
pcbolt's Avatar

Tyron -

It would be more accurate to say that as long as the expression within the parenthesis of the "while" statement IS NOT zero, continue with the loop. In other words you could write:

while(2){
  // this code executes...

In the statement:

while(ADCSRA & (1<<ADSC)){

...you are not using the logical compare AND statement which is &&, you are using a bitwise AND operator which is a single &. If you wanted the condition you described above, namely, ""WHILE" the ADCSRA register is ONE--AND--ADSC is ONE(on)", you would have to write it like this:

while(ADCSRA && (1<<ADSC)){  // note the double &&

The statement;

while(ADCSRA & (1<<ADSC)){

...will read as "Take the contents of register ADCSRA, bitwise AND it with the number 1 shifted left ADSC number of places (6 places in this case) and if the result is anything but zero, keep on looping".

When the ADC conversion is taking place the 6th bit in ADCSRA will be 1. We don't really know what the other bits are so we need an easy way to ask "If bit 6 in ADCSRA is 1, stay inside the while loop and do nothing". So without going into some ugly "for loops", we take the number 1 (which is 00000001 in binary) shift it over 6 places to get 01000000, then bitwise AND it with ADCSRA. If ADCSRA is x1xxxxxxx (where "x" can be either 1 or 0) and we bitwise AND it with 01000000 we would get 01000000 as a result no matter what the x's are. It's important to note here that the result is not 1 but actually 64 in decimal. If ADCSRA is x0xxxxxx, the result would be 00000000, and we would not execute the while loop.

May 30, 2012
by pcbolt
pcbolt's Avatar

Oh Tyron one other thing, the symbol ADSC isn't the value in the ADC register, it is only a substitution for the number 6. It is an easy way to remember where the "Start Conversion" bit placement is inside the ADCSRA register. It is actually defined when you placed "include <avr/io.h>" in your program. That file calls up another called "iom168p.h" where you'll find this:

#define ADSC 6

So every time the compiler sees ADSC it hard copies "6" in it's place.

May 31, 2012
by Ralphxyz
Ralphxyz's Avatar

pcbolt said:

ADSC isn't the value in the ADC register, it is only a substitution for the number 6.

Which is correct, BUT when one asks why is ADSC the number 6 you have to go to the ATmega168 specsheet.

23.9.2 ADCSRA – ADC Control and Status Register A

There has to be a reason why ADSC is 6.

ADSC is the sixth bit in the ADCSRA register.

It's funny I, not being a programmer, always think of the specsheet first and rarely, if ever, think of referencing avr/io.h and iom168p.h.

But pcbolt being the programmer that he is always has this logical programming perspective which I only wish I could develop.

When I see 1<<ADSC I do not see move 1 over 6 places to the left I see move one over to the place of the ADSC bit in the ADCSRA register.

I think 6 places to the left would probable be easier to grasp but it doesn't tell you why. One could go through life just thinking ADSC means 6 and never have to get confused reading the specsheet.

pcbolt I really appreciate your explanations.

Like your explanation above it really makes sense, thank you.

Ralph

June 01, 2012
by Tyron
Tyron's Avatar

OMG pcbolt,

I am giddy as a school girl, but haven't a clue what you and Ralph have just explained. I can tell, however, that it is "rudimentary" and gets at the heart of what's going on in there!! This opens up A huge adventure; better knowing what or how the questions should be asked to gain a little more understanding. Most information out there is to abstract or presumptuous, and maybe a little secret-squirrel. For example, "<<" as far as I have seen, has always meant "left-shift"---Now it makes sense, supports the context, and it still means "left-shift", by your explanation. Small but HUGE!!

Thanks for your patience, time, and effort (All you guys)! True product support, not the electronics part--the learning part.

Best Regards,

Tyron

December 07, 2012
by cadiz1
cadiz1's Avatar

// PIN DEFINITIONS: // // PC0 -- temperature sensor analog input

void adc_init() { // set analog to digital converter // for external reference (5v), single ended input ADC0 ADMUX = 0;

// set analog to digital converter

// to be enabled, with a clock prescale of 1/128 // so that the ADC clock runs at 115.2kHz. ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);

// fire a conversion just to get the ADC warmed up ADCSRA |= (1<<ADSC); }

Hi Everyone ,

The above code is a function definition. where is the function declaration(prototype) ?

Thanks Cadiz

December 07, 2012
by Ralphxyz
Ralphxyz's Avatar

The above code is a function definition. where is the function declaration(prototype) ?

I do not believe prototypes are "required" in C but if you wanted to add one they would go before

int main() { }

or in a library.

Ralph

December 07, 2012
by cadiz1
cadiz1's Avatar

Hi Ralph, Thanks I am pretty sure you do need them, all the C books I have explain this. They must be declared in some other file. I was also trying to find where uint16_t comes from.

Cadiz

December 07, 2012
by Noter
Noter's Avatar

A prototype is not necessary if a function declaration precedes usage of the function in the source file.

Any function that is called anywhere in the source must already be declared if you do not want to use prototypes. Since functions that are in external objects or library's are not defined anywhere in your source, their prototypes are usually in an include file.

Sometimes I prototype my local functions and put them after main() and other times I'll just declare them before my main() and forego the prototyping.

December 08, 2012
by cadiz1
cadiz1's Avatar

Hi Noter,

I am in agreement with what you have stated. There seems a little confusion. A function prototype is the same as a function declaration.

From Using borland c++ . A function declaration(also called the function prototype) tells the compiler about the function.

December 08, 2012
by Noter
Noter's Avatar

I am probably confused on the terms. What I mean is if you place your function above where you call it in the source you don't need separate prototypes.

December 08, 2012
by cadiz1
cadiz1's Avatar

New problem. I am confounded.

The adc_read() function is used in the trafficlight.c program. I cannot find the function definition in any of these files below. These header files should have this information. I did a search through all of them. where is the compiler picking up the function from?

include <stdio.h>

include <math.h>

include <avr/io.h>

include <avr/interrupt.h>

include <avr/pgmspace.h>

include <inttypes.h>

include "../libnerdkits/delay.h"

include "../libnerdkits/lcd.h"

include "../libnerdkits/uart.h"

December 08, 2012
by esoderberg
esoderberg's Avatar

Cadiz1,

The function is defined right in the traffic light code:

  uint16_t adc_read() {
  // 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.
  }
  // bit is cleared, so we have a result.

  // read from the ADCL/ADCH registers, and combine the result
  // Note: ADCL must be read first (datasheet pp. 259)
  uint16_t result = ADCL;
  uint16_t temp = ADCH;
  result = result + (temp<<8);

  // set ADSC bit to get the *next* conversion started
  ADCSRA |= (1<<ADSC);

  return result;
  }
December 09, 2012
by cadiz1
cadiz1's Avatar

Thanks esoderberg your right ! It is there and used in the tempsensor and the trafficlight programs.

I should have asked where is the function declaration for this function?

Thanks Again

December 09, 2012
by cadiz1
cadiz1's Avatar

I just had a look at the delay.c ,lcd.c and uart.c, the functions inside . The delay.h, lcd.h and uart.h contain the function declarations. This makes sense.

Now I have to track down the declarations for the adc_init() and adc_read().

December 09, 2012
by Noter
Noter's Avatar

adc_init() and acd_read() are not prototyped anywhere. Prototyping is not required if the function is defined before it is used.

http://en.wikipedia.org/wiki/Function_prototype

http://en.wikipedia.org/wiki/Forward_declaration

December 15, 2012
by cadiz1
cadiz1's Avatar

Hi Everyone,

Suppose ADCSRA is a 8 bit register. I put 11011010 into ADCRSA. Then I do :

ADCRSA &= ~(1 << 3);

I NOT bit 3 and then AND with 1101010(ADCSRA). This is how I read it. Am I correct?

December 15, 2012
by cadiz1
cadiz1's Avatar

2nd Version I think I made a mistake. Although the result will be the same.

ADCRSA &= ~(1 << 3)

translation : I set bit 3 to 1 , then NOT bit 3 (0), then AND.

This way bit 3 is always cleared.

December 15, 2012
by sask55
sask55's Avatar

This is the way I think of the statement

NOT involves the entire 8 bit byte. each of the bit values in the byte are changed ~ 11001100 = 00110011

OR and AND involve all 8 bits in two bytes and will result in a third byte value. In order to use NOT or OR I will require two bytes.

To clear any bit location in a byte we can use the AND statement, because a zero bit AND anything will always produce a zero.

So xxxxxxxx the bit values of x may be unknown

AND 01000100 A bit mask to clear the bit values in bit locations that contain a zero

Is 0x000x00 The resulting byte

To set any bit location in a byte we can use the OR statement, because a one bit OR anything will always produce a one.

So xxxxxxxx the bit values of x may be unknown

OR 01000100 A bit mask to set the bit values in bit locations that contain a one

Is x1xxx1xx The resulting byte

To clear a specific bit in the byte ADCRSA we will require the correct bit mask byte. If we want to clear the bit value in bit location 3 we will require a bit mask byte where the value in bit location 3 is zero and all the other bit values are one.

That is 11110111

To produce the bit mask we can use shift and NOT.

In this case

decimal 1 is binary 00000001

(1<<3) is shift 1 to the left 3 times resulting in binary 00001000

~(1<<3) is NOT(00001000) resulting in 11110111

Those two operations produce the correct bit mask.

ADCRSA &=~(1<<3); is shorthand for ADCRSA = ADCRSA AND NOT (00000001 shifted left three times)

if ADCRSA = 11011010

and ~(1<<3) = 11110111

ADCRSA 11011010

AND 11110111

Resulting 11010010 this byte value in placed back into ADCRSA

The value in bit location 3 is cleared all other bit locations remain as they where in ADCRSA before the AND.

I am not certain this explanation will make things any clearer.

December 15, 2012
by sask55
sask55's Avatar

Hi cadiz1

Just a suggestion for next time you may be asking about something.

I just noticed now that your question is not really related to this thread. You should have started a new thread with your question.

Darryl

December 18, 2012
by cadiz1
cadiz1's Avatar

Hi sask55,

Thanks for your very good explanation. I posted a question regarding bit shifting now in another thread. It is unanswered.

I tried and tried but couldn't get how 11011010 &=~(1<<3) = 11010010. my result was 110110010.

Tonight I noticed your line. ADCRSA &=~(1<<3); is shorthand for ADCRSA = ADCRSA AND NOT (00000001 shifted left three times)

There it is ! You started with 1 at bit location 0.

when I did the bit shift (1<<3) 1st shift = 00000001 , 2nd shift= 00000010. 3rd shift =000000100 . I should be 00001000 . I will check the other exercises

Thanks a billion

December 18, 2012
by Rick_S
Rick_S's Avatar

The reason (1<<3) is 00000001 shifted left 3 times is because 00000001 binary = 1 decimal = 01 Hexadecimal. The statement could just have as easily said (0b00000001 << 3) or (0b00000001 << 0b00000011) or (0x01<<0x03).

In AVR-gcc, Decimal numbers need no prefix to be used literally. Binary has a 0b prefix and Hexadecimal has the 0x prefix.

Rick

Post a Reply

Please log in to post a reply.

Did you know that 20 LEDs can be controlled from 11 microcontroller pins, to make a twinkling heart outline? Learn more...