Reading analog pin

I’m trying to understand this piece of code which is written for an AT90USB AVR:

int16_t AnalogRead(void)
{
    uint8_t low;
    ADCSRB = 0;
    ADMUX  = 0xC0;                // mux input
    ADCSRA = (1<<ADEN) | ((1<<ADPS2) | (1<<ADPS1)) | (1<<ADSC);  // conversion
    while (ADCSRA & (1<<ADSC)) ;
    low    = ADCL;                // read LSB first
    return (ADCH << 8) | low;     // read MSB only once!
}

I know it’s doing a read on an analog pin (which is then used to calculate battery voltage level), but I can’t figure out which. Is it being set by the ADMUX line?

Yes, the ADMUX register selects the analog input. You can read all about it in the datasheet (the full datasheet, not the "Summary").

Great, so I'm on the right track. So 0xC0 translates to what, 1100? Which is ADC6?

Does the AT90USB have analog inputs ? Which AT90USB ?

The ATmega328p sets the reference voltage in the two highest bits and the channel in the lowest bits. Hexadecimal 0xC0 = 1100 0000. For the ATmega328P that is channel 0 and reference internal 1.1V.

The AT90USB has no ADC and no ADCMPX register.

AT90USB1286, which has 8-channels, 10-bit ADC.

So, I guess I'm not understanding how that 0xC0 translates to which channel.

Taken from the 1286 datasheet:

MarkT: The AT90USB has no ADC and no ADCMPX register.

AT90USB646/647 as well as the AT90USB1286/1287 both have 8 channels, 10-bit ADC. AT90USB82/162 don't have ADC.

Ok, checking the datasheet of the AT90USB1286. According to chapter 26.9.1, writing 0xC0 to ADMUX is selecting channel ADC0 (single ended input) and internal reference of 2.56V.

The picture you are looking at (table 25-2) is in comparator mode. That is something else. Do you know the difference between an OpAmp and a Comparator ? If you don't, please don't bother with this.

Erdin: Ok, checking the datasheet of the AT90USB1286. According to chapter 26.9.1, writing 0xC0 to ADMUX is selecting channel ADC0 (single ended input) and internal reference of 2.56V.

I knew the voltage and I know, in theory, what the code is doing. It's figuring out how the address translates to which port that I'm having trouble with.

Erdin: The picture you are looking at (table 25-2) is in comparator mode. That is something else. Do you know the difference between an OpAmp and a Comparator ? If you don't, please don't bother with this.

There are many differences between an OpAmp and a Comparator and they should not be interchanged.

The code's already written on a device that's working - it's measuring battery voltage. I'm trying to understand it. I'm not the type of person that just takes any code, given or collected, and runs with it. I'd like to understand what it does first. Part of my confusion here is the '// conversion' line in the code that I'm deciphering still. Having never worked with actual port manipulations, I'm having a hard time. So pardon my ignorance for not knowing everything and wanting to learn.

The chip can be set in comparator mode, the result will be a digital signal.
You want to read an analog channel.

Table 26-4 is how to select the channel for the lower bits of the ADMUX register.

The ‘conversion’ line actually only starts the ADC.
If you read about the ADCSRA register (chapter 26.9.2) in the datasheet, you read:
ADEN : ADC enable, it must be ‘1’ to enable the ADC.
ADPS2, ADPS1 : prescaler bits, how fast or how slow the ADC should be.
ADSC : ADC start conversion. After this bit is set, the ADC starts it analog to digital converstion.

This “1<<ADEN” is how bit ‘ADEN’ is set to ‘1’.
That is how it was defined by Atmel and the avr gcc compiler.
Arduino has a macro for that: “bitSet( ADCSRA, ADEN);” or “ADCSRA = bit( ADEN) | bit( ADSC);
http://arduino.cc/en/Reference/Bit
http://arduino.cc/en/Reference/BitSet

How are you doing so far ? does this make it better to understand ?

Erdin:
The chip can be set in comparator mode, the result will be a digital signal.
You want to read an analog channel.

Yep, I figured that part out.

Erdin:
Table 26-4 is how to select the channel for the lower bits of the ADMUX register.

And that’s where I was stuck. I know 0xC0, and I know what that converts to, 1100 0000. Looking at that whole section, I now read:

Bit          7      6      5      4      3      2      1      0
           REFS1  REFS2  ADLAR  MUX4   MUX3   MUX2   MUX1   MUX0
Value        1      1      0      0      0      0      0      0

REFS1:0 both being set means internal 2.56V reference with an external cap on AREF
ADLAR having 0 written to it means the result is right adjusted
MUX4:0 all being 0 translates to ADC0

Yes?

Erdin:
The ‘conversion’ line actually only starts the ADC.
If you read about the ADCSRA register (chapter 26.9.2) in the datasheet, you read:
ADEN : ADC enable, it must be ‘1’ to enable the ADC.
ADPS2, ADPS1 : prescaler bits, how fast or how slow the ADC should be.
ADSC : ADC start conversion. After this bit is set, the ADC starts it analog to digital converstion.

I was just going over that part, trying to understand what each bit does.

Erdin:
This “1<<ADEN” is how bit ‘ADEN’ is set to ‘1’.
That is how it was defined by Atmel and the avr gcc compiler.
Arduino has a macro for that: “bitSet( ADCSRA, ADEN);” or “ADCSRA = bit( ADEN) | bit( ADSC);
http://arduino.cc/en/Reference/Bit
http://arduino.cc/en/Reference/BitSet

I understood how things were being enabled, just not how to read what was being done. So following that line and the documentation, I read:

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

1<<ADEN = Enable ADC
1<<ADPS2 and 1<<ADPS1 = division factor 64 (initial values dictates that ADPS0 is set to 0)
1<<ADSC = starts conversion

Correct?

Erdin:
How are you doing so far ? does this make it better to understand ?

It’s slowly coming to my aging brain … it’s getting there.

Yes, you got it all right.

The definitions like “ADEN” and “ADLAR” and so are the bit numbers.

For example REFS2 is number 6.
#define REFS2 6
It is that simple.

To set a bit number 6 in a register, it is possible to shift a ‘1’ six times to the left.
So “1<<REFS2” is a ‘1’ shifted 6 times to the left.

Everything else is in the datasheet.
Sometimes I have to read a part of the datasheet 5 times before I understand it, or maybe more with things like phase and frequency correct pwm mode.

KirAsh4:

MarkT:
The AT90USB has no ADC and no ADCMPX register.

AT90USB646/647 as well as the AT90USB1286/1287 both have 8 channels, 10-bit ADC.
AT90USB82/162 don’t have ADC.

I couldn’t guess that AT90USB meant that from your post! This is one of the reasons its useful
to provide a web link to the actual datasheet is so helpful in posts here - no confusion when there
are many similar parts.