AD-Wandler Atmega 32

Gast #600874
Hallo, ich möchte bei einem Gerät noch eine Batterie-Zustands-Anzeige 
machen. Dazu beutze ich den AD-Wandler des Controllers. Der AD-Wandler 
liefert doch einen Wert zwischen 0 und 1023 oder?
Ich möchte, dass ich nur Werte zwischen 0 und 7 (bzw. 1 und 8) erhalte. 
Dazu muss ich doch als Teilungsfaktor "128" einstellen, also ADPS2, 
ADPS1 und ADPS0 auf 1 setzen. Stimmt das so?
Ich erhalte auf meinem Display nämlich Ergebnisse, die nicht gerade der 
Realität entsprechen.

Vielen Dank!
#600880
Mit dem Teilerfaktor hat das ganze überhaupt nichts zu tun! Der 
definiert nur, mit welchem Takt der ADC arbeitet, also wie lange er für 
eine Wandlung braucht. In Deinem Fall musst Du aber das Ergebnis der 
Wandlung entsprechend weiterverarbeiten.

Zunächst mal solltest Du das ADLAR-Bit im ADMUX-Register setzen. Dann 
wird das Ergebnis schon mal linksbündig ausgegeben und Du musst nur noch 
das 8-Bit-Register ADCH auslesen (Wertebereich 0...255). Und den Wert 
teilst Du noch durch 32. Dann hast Du Deinen Wertebereich von 0...7.
Gast #600894
Lies dich mal im Dateblatt ein, wie das ADC-Ergebnis 'left-adjusted' 
eingestellt wird, dann bist du bei 8 bit (die unteren 2 bit kannst du 
ignorieren, indem du dann nur ADCH ausliest). Diese 8 bit nun 5 bit nach 
rechts schieben und du bist bei 3 bit Auflösung (0..7). In Assembler und 
in C die schnellste Variante.
Gast #600898
Wenn dir 0..3 (also 1..4) als Wertebereich ausreichen, dann nimm doch 
einfach right-adjusted und lies nur das ACDH aus, das denthält dann 
werte zwischen 0...3
Gast #601424
Also hier ist mal der Quellcode, hab im Moment noch Probleme mit dem 
AD-Wandler. Wenn ich den Pin am Controller auf Masse ziehe, krieg ich 
immer noch einen hohen Wert, also eigentlich immer...
1
uint16_t ReadChannel(uint8_t kanal)
2
{
3
  uint8_t i;
4
  uint16_t result;
5

6
  ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0);      // Frequenzteiler auf 128 setzen --> 8 Zustände 
7
                                            
8
  ADMUX = kanal;                              // Kanal waehlen
9
  ADMUX |= (1<<REFS1) | (1<<REFS0);         // interne Referenzspannung nutzen 
10

11
/*  // Dummy-Messung (wird bei ADC-Initialisierung selbständig ausgeführt...
12

13
  ADCSRA |= (1<<ADSC);                      // eine ADC-Wandlung 
14
  while ( ADCSRA & (1<<ADSC) ) {
15
     ;                           // auf Abschluss der Konvertierung warten 
16
  }
17
  result = ADCW;                    // ADCW muss einmal gelesen werden,
18
                                    // sonst wird Ergebnis der nächsten Wandlung
19
                                    // nicht übernommen.
20
*/
21
  // Eigentliche Messung
22

23
  result = 0; 
24
    ADCSRA |= (1<<ADSC);                    // eine Wandlung "single conversion"
25
    while ( ADCSRA & (1<<ADSC) ) {
26
      ;                         // auf Abschluss der Konvertierung warten
27
    }
28
    result = ADCW;                    // Wandlungsergebnis
29
  ADCSRA &= ~(1<<ADEN);                     // ADC deaktivieren
30
 
31
  return result;
32
}
#601434
Wundert mich nicht wirklich. Im Datenblatt steht eindeutig, dass das 
erste Ergebnis nach dem Start des ADC u.U. für die Tonne ist. Warum hast 
Du die Dummy-Wandlung auskommentiert? Die könnte das Problem nämlich 
beheben. Und je nachdem, wie oft gewandelt werden soll, ist es auch 
unsinnig, den ADC nach jeder Wandlung wieder zu deaktivieren. Dann kann 
man sich auch die Dummy-Wandlung sparen (außer beim ersten Mal, aber das 
kann man in main nach der Initialisierung machen).

Außerdem solltest Du bei Änderungen im Code auch die Kommentare 
entsprechend anpassen. Das mit "Frequenzteiler auf 128 setzen --> 8 
Zustände" hatten wir schließlich schon geklärt (hoffe ich jedenfalls).
Gast #601451
Du kannst auch vor der ersten Wandlung 120µs Pause machen (bzw. etwas 
Anderes), dann kommt auch bei der ersten Wandlung was Vernünftiges 
'raus.
Zwischen dem Einstellen der Betriebsart und der nächsten Messung 120µs 
Pause machen.
Gast #601456
Also hab jetzt die Dummy-Wandlung wieder drin. Bekomme als Ergebnis 
jedoch immer 255 angezeigt. Sogar wenn ich die den ADC-Kanal auf Masse 
lege. Ich hab aber einen anderen Punkt auf der Platine gefunden 
(übrigens auch auf Masse-Potenzial!!!!!!!!), bei dem dann 31 angezeigt 
wird.
Gast #601487
Nein hab ich nicht, ist laut Datenblatt auch nicht unbedingt nötig. Bei 
mir ist die Genauigkeit sowieso nicht so wichtig, ich brauch ja nur 3 
Bits.
Gast #601504
An dem Kondensator liegts ziemlich sicher nicht, der ist zwar wichtig, 
aber wenn er wirklich nur die obersten Bits braucht kann man den auch 
weglassen. Wenn man feststellt, dass diese dennoch flattern sollten kann 
man den auch noch einbauen. Aber momentan scheint er immer den gleichen 
Wert zu bekommen und da ist der Kondensator kaum schuld.
Ich will damit nicht sagen, dass es nicht nötig ist diesen Kondensator 
einzubauen, aber eben...
Gast #601543
Das Ding ist ne fertige Platine, bei der ich noch den Batteriezustand 
aufs Display machen sollte. Da der Controller so klein ist, habe ich von 
jemand anderem einen losen Draht an den ADC-Pin anbringen lassen. Und 
ich hab jetzt zweieinhalb Stunden gebraucht um herauszufinden, dass der 
Draht Isolierlack drauf hatte ^^

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 19 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

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.