AD-Wandler Atmega 32

Gast #600874
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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 #601424
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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 #601504
Lesenswert?

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
Lesenswert?

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

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