Getting the Full 10-bits from the ADC (Analog to Digital Converter)
This is where we UP the anty with Mrs. ADC. Do you have the faith? Do you think
she will be able to handle that much cash?!? She's pretty stressed as it is! She
is sensitive to sound, she's dishonest, and she makes mistakes all the time. Let's
see how she does.
Actually, she wasn't that bad with the 256 currency exchange mode. But that's where
it ends. The 10-bit 1024 exchange mode is a bit more of an issue with Mrs. ADC.
She gets real nervous with that much currency! Noice from Breadboardville, Mr. Pot
and King Core is making her crazy. There is cacophony all around her.
This time, Mr. Cap is really necessary! Fat Cap would do a good job, but Mr. Fat
Cap is no match for the upheaval going on at Breadboardville. Breadboardville is
a town with gusts of wind that can wash away rain voltage currency. If there are
waves of this untamed currency in the air, Breadboardville is sure to pick it up.
See the next chapter to see if Mr. Cap can launder his voltage currency well enough
to overcome this turbulence! We will also meet Mr. Gravity! The tipsy fellow down
the metal street.
So, how do we capture the 10-bit number currencies? We only need to look at another
register. For the 8-bit number, we were looking at the ADCH (Analog to Digital Conversion
Result High) and when the ADLAR in ADMUX is set, then the ADCL is left justified
and the ADCL will contain a number between 0-256. When we get ADCL (Analog to Digital
Conversion Result Low) involved, then we can capture the two extra bits that exist
in the 10-bit number.
By using the ADCH for just receiving 0-255, we are essentially skipping every
4th number in the actual ADC. By including the ADCL, we are able to capture the
extra 4 numbers in-between each of the ADCH numbers.
Please don't glaze over the following information!!! If you don't
understand shifting operations (>> or <<), then this will really help you. Read
it carefully!
First, we utilize a 16-bit variable to hold the 10-bit number (in the program, I
call it "theTenBitResults"):
So, theTenbitResults starts off like this:
bit15
|
bit14
|
bit13
|
bit12
|
bit11
|
bit10
|
bit9
|
bit8
|
bit7
|
bit6
|
bit5
|
bit4
|
bit3
|
bit2
|
bit1
|
bit0
|
With ADLAR = 1:
ADCL starts off with these bits (remember 2 bits have 4 possibilities 0, 1, 2 and
3):
bit1
|
bit0
|
----
|
----
|
----
|
----
|
----
|
----
|
Two of the 10 total bits.
And ADCH starts off with these bits (remember that 8 bits have 256 possibilities):
bit9
|
bit8
|
bit7
|
bit6
|
bit5
|
bit4
|
bit3
|
bit2
|
The remaining 8 of the total 10 bits.
Shifting ADCL to the right 6 places using this: ADCL >> 6, we would get:
----
|
----
|
----
|
----
|
----
|
----
|
bit1
|
bit0
|
If by stating theTenBitResult |= ADCL >> 6; theTenbitResults would look like this:
----
|
----
|
----
|
----
|
----
|
----
|
----
|
----
|
----
|
----
|
----
|
----
|
----
|
----
|
bit1
|
bit0
|
The ADCL is shifted to the right by 6 places (moving it all the way to the right)
Now we just need to get the ADCH into the theTenbitResults variable. All we need
to do is make room for the two bits of the ADCL, so by shifting ADCH two places
to the left and still applying the ADCL, we get: theTenBitResult |= ADCH << 2 |
ADCL >> 6
----
|
----
|
----
|
----
|
----
|
----
|
bit9
|
bit8
|
bit7
|
bit6
|
bit5
|
bit4
|
bit3
|
bit2
|
bit1
|
bit0
|
And then Bob's your Uncle, if you like left adjusted stuff. Let see how to do it
right adjusted.
Don't worry about the 6 un-used spaces in the 16-bit number. We really don't have
any other options.
With ADLAR = 0:
ADCL starts off with these bits:
bit7
|
bit6
|
bit5
|
bit4
|
bit3
|
bit2
|
bit1
|
bit0
|
Eight of the 10 total bits (the 8 low bits).
And ADCH starts off with these bits:
----
|
----
|
----
|
----
|
----
|
----
|
bit9
|
bit8
|
The remaining 2 of the total 10 bits (the two high bits).
Shifting ADCH to the left 8 places using this: ADCH << 8, we would get:
bit9
|
bit8
|
----
|
----
|
----
|
----
|
----
|
----
|
----
|
----
|
If by stating theTenBitResult |= ADCH << 8; theTenbitResults would look like this:
----
|
----
|
----
|
----
|
----
|
----
|
bit9
|
bit8
|
----
|
----
|
----
|
----
|
----
|
----
|
----
|
----
|
The ADCH is shifted to the ledft by 8 places top make room for the low 8 bits.
All we need to do now is to place the ADCL into the variable since the lower 8 bits
would just naturally be set into the correct places: theTenBitResult |= ADCH <<
8 | ADCL
----
|
----
|
----
|
----
|
----
|
----
|
bit9
|
bit8
|
bit7
|
bit6
|
bit5
|
bit4
|
bit3
|
bit2
|
bit1
|
bit0
|
And there you go!
Lets see how this program may appear (I selected the latter of the two approaches
with ADLAR = 0):
#include <avr/io.h>
#include <avr/interrupt.h>
#include "MrLCD.h"
int main(void)
{
InitializeMrLCD();
Send_A_StringToMrLCDWithLocation(1,1,"ADC Result:");
ADCSRA |= 1<<ADPS2;
ADMUX |= (1<<REFS0) | (1<<REFS1);
ADCSRA |= 1<<ADIE;
ADCSRA |= 1<<ADEN;
sei();
ADCSRA |= 1<<ADSC;
while (1)
{
}
}
ISR(ADC_vect)
{
uint8_t theLowADC = ADCL;
uint16_t theTenBitResults = ADCH<<8 | theLowADC;
Send_An_IntegerToMrLCD(13,1,theTenBitResults, 4);
ADCSRA |= 1<<ADSC;
}