ADC channel via ADMUX ändern?

OP #6212485
Lesenswert?

Hallo,

wieso muss ich den ADC channel in ADC_init vorgeben, ein ändern in 
ADC_read bringt kein Ergebnis (der ADC gibt dann nur 1023 aus)?
1
void ADC_init() {
2

3
  ADMUX = 0;
4

5
  ADCSRA |= (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);   // Activate ADC with Prescaler 128 --> 8Mhz/128 = 62.5kHz
6

7
  ADMUX |= (1<<REFS1) | (1<<REFS0);                // Interne Vref beutzen
8

9
  ADCSRA |= (0<<ADLAR);                      // left aligned = 1
10

11
  }
12

13
void ADC_read(char ADC_channel) {
14

15
  //ADMUX = ADC_channel;          // Select pin ADC0 using MUX
16
    
17
  ADCSRA |= (1<<ADSC);                // eine Wandlung "single conversion"
18
    
19
  while ( ADCSRA & (1<<ADSC) ) {;}       // auf Abschluss der Konvertierung warten
20
 
21
  
22
    adc_value = ADCL;               // value is uint16_t x
23
    adc_value += (ADCH<<8);         // ...use LOW byte of ADC result
24
                              // ...add HIGH bye of ADC result
25

26
  }

Danke, Klaus.
Gast #6212492
Lesenswert?

ATMEGA 328?

Änderungen an ADMUX wirken sich erst bei der nächsten Konvertierung aus, 
wenn bereits eine Konvertierung läuft, sonst erst bei der übernächsten. 
Wenn ADMUX geschrieben wird, landet das erst in einem Zwischenregister, 
erst am Ende der Konvertierung wird der Multiplexer umgeschaltet.
Gast #6212509
Lesenswert?

> -> Das wäre doch VOR der Wandlung? Hatte ich auch schon im DaBla
> gelesen, meinte es aber damit einzuhalten?
>

Wie gesagt: Die Umschaltung erfolgt am Ende jeder Wandlung. Warte mal 
das Ende der 1. Wandlung ab und starte eine neue. Dann erhältst du das 
richtige Ergebnis.
Gast #6212520
Lesenswert?

Das, was Mario M. und Hmmm oben gesagt haben, stimmt natürlich. Ich 
hatte oben auch nicht ganz recht: Bei der ersten Konvertierung werden 
MUX und REFS doch upgedatet. Nur im free running mode passiert das nur 
am Ende jeder Konvertierung.
Datenblatt:
Figure 92. ADC Timing Diagram, First Conversion (Single Conversion Mode)
Figure 93. ADC Timing Diagram, Single Conversion
Figure 94. ADC Timing Diagram, Free Running Conversion

Trotzdem sollte man nach dem Ändern der Referenzspannungsquelle  das 
Ergebnis der nächsten Konvertierung wegwerfen. (Abschnitt ADC Voltage 
Reference, letzter Satz)
#6212533
Lesenswert?

//ADMUX = ADC_channel;          // Select pin ADC0 using MUX

wie bereits gesagt, werden hier alle anderen Bits in diesem Register 
gelöscht, was im Allgemeinen NICHT erwünscht ist. Besser so.
1
ADMUX = ADMUX & ~0xF | ADC_channel & 0xF;

Damit werden nur die MUX-Bits in ADMUX gelöscht und ADC-channel außerdem 
auf 0-15 begrenzt, ein fälschlicher Aufruf mit >15 macht die anderen 
Bits nicht kaputt. Nennt sich defensives Programmieren. Siehe auch 
Bitmanipulation.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren