Forum: Mikrocontroller und Digitale Elektronik ADCMUX Atmega328P


von Frank W. (frankydaniels)


Lesenswert?

Hallo Zusammen,

ich habe mal wieder ein Problem mit meinem ADC beim Atmega328P.

Nachdem jetzt nun die Initialisierung korrekt ist wird der Interrupt 
durch den ADC aufgerufen. Ich möchte nun für einen Kanal 200 Werte und 
dann für den anderen Kanal 200 Werte aufnehmen. Dies soll immer im 
Wechsel im Freerunningmode passieren. Am Ende soll dies eine 
Effektivwertmessung für zwei unterschiedliche Sinussignale geben.

Hier die Initialisierung:
1
//ADC Init
2
  ADMUX = (1 << REFS0);//interne Referenz = Betriebsspannung
3
  
4
  ADCSRA = (1<<ADATE) | (1 << ADEN) | (1 << ADIE) | (1 << ADPS2) | (1 << ADPS1);
5
  //Free Running mode, ADC=Ein, ADC Interrupt enable, Prescaler 64 = 125kHz bei F_CPU = 8Mhz
6
    
7
  sei();                            // Set the I-bit in SREG
8
9
  ADCSRA |= (1<<ADSC); //AD-Wandler starten (Free Running Mode)

Nun habe ich wohl ein Problem mit meinem Mux. Wenn ich Wandlungen auf 
einen Kanal durchführe funktioniert alles.
Wenn ich nun jedoch das oben Geschilderte umsetzen möchte gibt der 
Wandler immer nur den Wert 1024 aus. Ich weis aber nicht was ich falsch 
mache. Die Signale liegen an den Pins ADC1 und ADC0.

Hier meine ADC Interrupt routine:
1
uint16_t ADC1_Data[200]; 
2
uint16_t ADC2_Data[200];
3
uint8_t ADC_Zaehl=0;
4
uint8_t toggle = 0;
5
6
ISR(ADC_vect)
7
{
8
  if (toggle)
9
  {
10
    ADC1_Data[ADC_Zaehl] = ADCW&0x03FF; 
11
    ADC1_Data[ADC_Zaehl]= ADC1_Data[ADC_Zaehl];
12
    if (ADC_Zaehl>=199)
13
    {
14
      ADMUX = (1<< MUX0);
15
      ADFlag = 1;
16
      ADC_Zaehl=0;
17
      toggle=0;
18
    }
19
    else
20
    {
21
      ADC_Zaehl++;
22
    }
23
  }
24
  else
25
  {
26
    //cli();
27
    ADC2_Data[ADC_Zaehl] = (ADCW&0x03FF);
28
    //sei();
29
    ADC2_Data[ADC_Zaehl]= ADC2_Data[ADC_Zaehl];
30
    if (ADC_Zaehl>=199)
31
    {
32
      ADMUX = 0x00;
33
      ADFlag = 1;
34
      ADC_Zaehl=0;
35
      toggle=1;
36
    }
37
    else
38
    {
39
      ADC_Zaehl++;
40
    }
41
  }  
42
}

Die variable Toggle gibt an welcher Kanal gerade dran ist. Die Variable 
ADFlag gibt an wann ein Datenarray fertig beschrieben ist um somit die 
spätere Auswertung zu starten.

Muss ich beim ADMUX auf irgendetwas achten? Im Datenblatt habe ich 
nichts nennenswertes gefunden.

Danke schon mal für eure Antworten

Mfg Franky :)

von Frank W. (frankydaniels)


Lesenswert?

Bitte nicht an den unnötigen Zeilen stören wie:
1
ADC2_Data[ADC_Zaehl]= ADC2_Data[ADC_Zaehl];

Das sind noch Überreste von verschiedenen Versuchen :-P

von Felix P. (fixxl)


Lesenswert?

Gewöhne dir bitte an - denn das war schon im ersten Thread das Problem, 
Register nicht mit der Holzhammermethode
1
REGISTER = WERT
 zu beschreiben, sondern setze oder lösche die jeweiligen Bits gezielt 
durch
1
REGISTER |= 1<<BITNUMMER // setzen
2
REGISTER &= ~(1<<BITNUMMER) // löschen

Wenn du ADMUX = 1<<MUX0 setzt, löschst du dabei die Einstellung für die 
Referenzspannung aus der Initialisierung, versuche es mal mit ADMUX |= 
1<<MUX0

von Frank W. (frankydaniels)


Lesenswert?

Felix Pflaum schrieb:
> Gewöhne dir bitte an - denn das war schon im ersten Thread das Problem,
> Register nicht mit der Holzhammermethode
1
REGISTER = WERT
 zu
> beschreiben, sondern setze oder lösche die jeweiligen Bits gezielt durch
>
1
REGISTER |= 1<<BITNUMMER // setzen
2
> REGISTER &= ~(1<<BITNUMMER) // löschen
>
> Wenn du ADMUX = 1<<MUX0 setzt, löschst du dabei die Einstellung für die
> Referenzspannung aus der Initialisierung, versuche es mal mit ADMUX |=
> 1<<MUX0

Ohman danke, es funktioniert. Zweimal hintereinander den gleichen Fehler 
-.-

Danke nochmals :) Ich werde jetzt in Zukunft versuchen es immer so zu 
machen :)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.