Ganz ehrlich, ich verstehe deinen Code nicht wirklich 
Aber mal ein paar Grundsätzliche Dinge zum ADC und den verschiedenen Modi.
Free Running: Es wird ständig gewandelt, und es steht auch zu jedem Zeitpunkt ein gültiges Ergebnis in ADC. Das heißt im Umkehrschluss, wenn du in irgend einer Funktion mit einer while Schleife auf etwas warten musst, ist grundlegend etwas verkehrt, denn warten musst du in keinem Fall. Du kannst jederzeit einfach ADC auslesen (Wenn das zu schnell geht, hast du logischerweise mehrmals ein Messwert von dem gleichen Zeitpunkt, der ADC ist ja nicht beliebig schnell)
Single Conversion: Du bestimmt, wann eine Messung gestartet wird. Jetzt musst du auch tatsächlich abfragen (oder ausreichend lange etwas anderes tun, Stichwort Timer) ob die Wandlung abgeschlossen ist, und kannst dann dein Ergebnis holen.
Du versuchst hier gerade eine Kombination aus beidem (Free Running + Warteschhleifen). Der Free Running Mode bringt diverse Stolpersteine mit sich, und ist in den allermeisten Fällen kontraproduktiv.
Beispiel Single Conversion:
Code:
void adc_init (void)
{
ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0); //prescaler = 128
ADMUX = (1<<REFS1) | (1<<REFS0); // interne Referenzspannung
ADCSRA |= (1<<ADSC); //Erste Messung anschubsen
while (ADCSRA & (1<<ADSC)); //Auf abschluss der Messung warten
unsigned int dummy = ADC; //Und ersten Messwert wegwerfen
}
unsigned int read_adc (unsigned char channel){
ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F); //Logisches geraffel damit die restlichen Bits in ADMUX erhalten bleiben
ADCSRA |= (1<<ADSC); //Messung anschubsen
while (ADCSRA & (1<<ADSC)); //warten...
return ADC;
}
int main(){
adc_init();
unsigned int ch1, ch2;
ch1 = read_adc(1); //ADC Channel 1 wandeln
ch2 = read_adc(2); //ADC Channel 2 wandeln
}
Code ungetestet, sollte aber das Prinzip veranschaulichen. Vom Free Running Mode würde ich die finger lassen.
Lesezeichen