
Atmega324P
$8.50

20x4 LCD
$18.50

16x2 LCD
$12.50

Breadboard
$7.95

Clear Breadboard
$8.50

Red LED 1.7v
$0.34

Green LED 2.2v
$0.34

Yellow LED 2v
$0.34

330ohm Resistor
$0.24

0.1uf Capacitor
$0.24

10k Potentiometer
$0.85

20k Potentiometer
$0.85

10uF Capacitor
$0.44

Jumper Wires
$12.00
Reading Multiple ADC Channels on the AVR Atmega32
What does multiple channels mean? If you have more than one analog voltage source,
more than one sensor, for instance, you can read all of them as long as the number
of sources is fewer than the number of ADC pins you have on your microcontroller.
With the Atmega32, there are 8 ADC pins. The only thing to keep in mind when programming
the ADC to read multiple channels is that only one channel can be used in the conversion
at a time.
If we had two sensors, and we are using channel (pin) 3 and 4 to read each sensor,
we would first need to set the channel for 3 and then start a conversion. After
the conversion is finished and the number is captured, then the channel can be switch
to 4 and that number can be captures. These processes of getting the ADC results
for each channel can be done in a loop and displayed on the LCD.
The ADC is initialized as we did with the accelerometer readings and in this case,
we are connecting the X axis of the accelerometer to channel 0 and the Y axis to
channel 1. There is not preinitialization of the ADC channel before we enable the
ADC because we are starting with channel 0 which is the default channel.
In the interrupt service routine (the routine starting with ISR), you will see a
few new statements, such as switch and case. This is a very nice way to make a selection
according to a value contained by a variable. It's like making a restaurant menu
selection. The variable that is contained within parentheses after the word switch
is the restaurant customer's selection and the various cases listed below are all
the menu selections.
#include <avr/io.h>
#include <avr/interrupt.h>
#include "MrLCD.h"
int main(void)
{
InitializeMrLCD();
Send_A_StringToMrLCDWithLocation(1,1,"X:");
Send_A_StringToMrLCDWithLocation(1,2,"Y:");
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 theLow = ADCL;
uint16_t theTenBitResult = ADCH<<8 | theLow;
switch (ADMUX)
{
case 0xC0:
Send_An_IntegerToMrLCD(4, 1, theTenBitResult, 4);
ADMUX = 0xC1;
break;
case 0xC1:
Send_An_IntegerToMrLCD(4, 2, theTenBitResult, 4);
ADMUX = 0xC0;
break;
default:
//Default code
break;
} ADCSRA |= 1<<ADSC;
}