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

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.