Hallo,
ich habe Probleme bei meinem AVR den Adc mit zwei Kanälen zu betreiben. Habe jetzt schon 3 Tage damit herumgespielt und komme einfach nicht mehr weiter.
Ich poste am besten erst mal den C Code, der bei mir in einem sourcefile names timer.c untergebracht ist:

Code:
#include "include.h"

uint16_t current_adc_null =0;
uint16_t old_adc_null     =0;
uint16_t current_adc_eins =0;
uint16_t old_adc_eins     =0;



void adc_init (void)
{
  ADCSRA = (1<<ADEN) |(1<<ADSC) | (1<<ADATE) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);   // free running prescaler = 128
  ADMUX  = (1<<REFS1) | (1<<REFS0) | (1<<MUX0);	 // interne Referenzspannung, Mux0 = Pin ADC1 
 // auf Abschluss der Konvertierung warten
 // ADCSRA |= (1<<ADSC);
 //	while(ADCSRA & (1<<ADSC));     geht nicht !

         
// einmalige Messung
 current_adc_null = ADCL;
 current_adc_null |= (ADCH<<8);
 current_adc_null = 0;
}
uint16_t read_adc0 (void){

  unsigned char sreg;
  sreg = SREG;
  cli ();
  current_adc_null = ADC;
 SREG = sreg;
 return current_adc_null;}

uint16_t read_adc1 (void){
     uint8_t admux;
     uint8_t sreg;
     sreg = SREG;
     admux = ADMUX;
   

    ADMUX  = (1<<REFS1) | (1<<REFS0) | (1<<MUX1); //ADC2
    while (!(ADCSRA & (1<<ADIF))){}  //Wait until current conversion is complete
    ADCSRA |= (1<<ADIF);  //clear interrupt Flag again
    while (!(ADCSRA & (1<<ADIF))){} //Wait until new conversion is complete
    ADCSRA |= (1<<ADIF);  //reset Flag 
    while (!(ADCSRA & (1<<ADIF))){} //Wait until new conversion is complete
 cli ();
current_adc_eins = ADC;

 ADMUX = admux;
 SREG = sreg;
 return current_adc_eins;
}
Der Code ist so aufgebaut, dass Adc0 ganz normal gelesen wird, während bei der Messung von Adc1 erst das Admux Register zum Einstellen des Kanals gesichert wird, dann auf den neuen Kanal von Adc1 umgestellt wird und danach der alte Zustand wiedergehellt wird.

Dazu habe ich gleich zwei Fragen:
1. Mein Kontroller kommt aus folgender while Schleife, die ich oben auskommentiert habe, nicht mehr raus:
// ADCSRA |= (1<<ADSC);
// while(ADCSRA & (1<<ADSC));
Ist das normal?
2. Warum muss ich folgende Anweisungen aus dem Code mindestens 3 mal hintereinander verwenden:
ADCSRA |= (1<<ADIF); //reset Flag
while (!(ADCSRA & (1<<ADIF))){} //Wait until new conversion is complete
Wenn ich die Anweisung nur zwei mal schreibe, hat current_adc_null den gleichen Wert wie current_adc_eins.

Da die Adc Werte bei interner Referenzspannung und Kondensator am Aref Pin immer noch zwischen Werte von +/- 5 schwanken habe ich in meiner Main.c folgende If Schleifen eingebaut, deren Funktionsrümpfe nur aufgerufen werden sollen, wenn sich die Adc Werte außerhalb der Schwankungen geändert haben:

Code:
// Adc0 einlesen
read_adc0();
if  ((old_adc_null - 6) > current_adc_null  || (old_adc_null + 6) < current_adc_null ) {        

 old_adc_null = current_adc_null;


}

  //Adc1 einlesen
  read_adc1();
if ((old_adc_eins - 6) > current_adc_eins || (old_adc_eins + 6) < current_adc_eins ) {

  old_adc_eins = current_adc_eins ;


	}
In den Schleifen lasse ich natülich auch noch andere Befehle ausführen, wie zum Beispiel das Beschreiben des Displays mit den aktuellen ADC Werten und das Setzen von OCP Timerwerten.
Nun zu meinem Problem: So wie oben gepostet funktioniert funktioniert das ganze nicht, denn current_adc_null hat den selben Wert wie current_adc_eins und die erste if Schleife wird auch nur aufgerufen, wenn sich current_adc_eins ändert.
Lasse ich die Anweisung " old_adc_eins = current_adc_eins ;" in der zweiten If Schliefe oben weg, werden beide Adc Werte korrekt auf dem Display ausgegeben. Es scheint also alles zu funktionieren, bis auf die Tatsache, dass die Schwankungen von current_adc_eins nicht ausgeblendet werden.
Ich versteh überhaupt nicht wie das sein kann. Normalerweise dürfte doch current_adc_eins mit current_adc_null überhaupt nicht zusammenhängen, oder?
Wenn ich die Bedingungen in der If Schleife zum Ausblenden der Schwankungen einfach weglasse und beide Werte permanent auf dem Display ausgeben lasse, funktioniert es auch wieder (auch mit old_adc_eins = current_adc_eins )

Letzte und wichtigste Frage:
Ist es normal, dass die Adc Werte um bis zu +/- 100 Schwanken, wenn ich am PC6 Pin über einen 100 Ohm widerstand die Basis eines Transistor schalte?

Ich hoffe man kann das nachvollziehen, da es wohl nicht so einfach ist sich hier reinzudenken. Ich wäre Euch trotzdem sehr dankbar, wenn mir jemand helfen könnte, da ich jetzt schon viel Zeit reininvestiert habe und das Teil endlich zum Laufen bekommen möchte/muss.

MfG
Destrono