www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AREF schwingt sägezahnförmig


Autor: Georg (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe bei einem ATmega128L (3.3V) probleme mit dem ADC. Ich bekomme 
keine vernünftigen Werte. Ich messe an ADC0 und ADC1. Ich bekomme 
jeweils einen Wert um die 350 raus (int16t_t-Wert), egal welche Spannung 
am den Eingängen anliegt. Ich verwende den Code aus dem 
AVR-ggc-Tutorial.
uint16_t ReadChannel(uint8_t mux)
{
  uint8_t i;
  uint16_t result;
 
  ADMUX = mux;                      // Kanal waehlen
  ADMUX |= (1<<REFS1) | (1<<REFS0); // interne Referenzspannung nutzen
 
  ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0);    // Frequenzvorteiler 
                               // setzen auf 8 (1) und ADC aktivieren (1)
 
  /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
     also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
  ADCSRA |= (1<<ADSC);              // eine ADC-Wandlung 
  while ( ADCSRA & (1<<ADSC) ) {
     ;     // auf Abschluss der Konvertierung warten 
  }
  result = ADCW;  // ADCW muss einmal gelesen werden,
                  // sonst wird Ergebnis der nächsten Wandlung
                  // nicht übernommen.
 
  /* Eigentliche Messung - Mittelwert aus 4 aufeinanderfolgenden Wandlungen */
  result = 0; 
  for( i=0; i<4; i++ )
  {
    ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
    while ( ADCSRA & (1<<ADSC) ) {
      ;   // auf Abschluss der Konvertierung warten
    }
    result += ADCW;        // Wandlungsergebnisse aufaddieren
  }
  ADCSRA &= ~(1<<ADEN);             // ADC deaktivieren (2)
 
  result /= 4;                     // Summe durch vier teilen = arithm. Mittelwert
 
  return result;
}


temp1 = ReadChannel(0);
temp2 = ReadChannel(1);



Ich habe mal mit dem Oszi die Pins durchgemessen und festgestellt, das 
AREF sägezahnförmig zwischen 1 V und 2,5 V schwingt. Frequenz ca. 1Hz.
Ist das normal?

Es kommt vor, das an den Eingängen manchmal neg. Spannung von ca. -4V 
anliegen. Ich habe die Eingänge mit 4k7 Widerständen abgesichert. Könnte 
der ADC beschädeigt worden sein.

Jemand eine Idee wo mein Problem liegen könnte?


Gruß
Georg

Autor: Εrnst B✶ (ernst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Georg schrieb:

>   ADMUX = mux;                      // Kanal waehlen
>   ADMUX |= (1<<REFS1) | (1<<REFS0); // interne Referenzspannung nutzen

Schaltet die Referenzspannung für jede Messung an und wieder aus...
Besser:
ADMUX = mux | (1<<REFS1) | (1<<REFS0);

Autor: Philipp (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Negative eingangsspannungen mögen die nunmal garnich gerne..
wenn dann musst du deine 4k7 nehmen und danach mit dioden (am besten 
shotky) gegen GND absichern. das mag er womöglich noch vertragen

Autor: Georg (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok ... und ich messe jede Sekunde ein mal -> daher wohl die 1Hz.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mach mal ne Brücke über den 47 Ohm R.

Autor: Georg (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@holger

Die Spannung am AVCC sieht am Oszi gut aus. Trotzdem brücken?

Autor: Εrnst B✶ (ernst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Georg schrieb:

> Die Spannung am AVCC sieht am Oszi gut aus. Trotzdem brücken?

eigentlich gehört da eine kleine Spule oder ferritperle hin, 47Ohm sind 
"gefühlt" etwas viel.
Aber egal: Erst die geänderte Software testen, dann notfalls zum 
Lötkolben greifen.

Autor: Georg (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Code soll also so aussehen?!

uint16_t ReadChannel(uint8_t mux)
{
  uint8_t i;
  uint16_t result;
 
  ADMUX = mux | (1<<REFS1) | (1<<REFS0);
 
  ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0);    // Frequenzvorteiler 
                               // setzen auf 8 (1) und ADC aktivieren (1)
 
  /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
     also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
  ADCSRA |= (1<<ADSC);              // eine ADC-Wandlung 
  while ( ADCSRA & (1<<ADSC) ) {
     ;     // auf Abschluss der Konvertierung warten 
  }
  result = ADCW;  // ADCW muss einmal gelesen werden,
                  // sonst wird Ergebnis der nächsten Wandlung
                  // nicht übernommen.
 
  /* Eigentliche Messung - Mittelwert aus 4 aufeinanderfolgenden Wandlungen */
  result = 0; 
  for( i=0; i<4; i++ )
  {
    ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
    while ( ADCSRA & (1<<ADSC) ) {
      ;   // auf Abschluss der Konvertierung warten
    }
    result += ADCW;        // Wandlungsergebnisse aufaddieren
  }
  ADCSRA &= ~(1<<ADEN);             // ADC deaktivieren (2)
 
  result /= 4;                     // Summe durch vier teilen = arithm. Mittelwert
 
  return result;
}


Autor: Spezi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

wenn der Controller nicht Strom sparen muss, lässt man den ADC nach der 
Initialisierung dauerhaft eingeschaltet und triggert ihn bei Bedarf 
(nach Auswahl des Kanals). Das spart das Dummy-Read des Wertes (ausser 
beim ersten Einschalten des ADC).

Initialisierung des ADC wäre dann:

>> ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0);    // Frequenzvorteiler

und wird zu Beginn des Programms aufgerufen.
Der Rest läuft dann in der Routine ab, aber ohne die Zeilen

> ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0);
> ADCSRA &= ~(1<<ADEN);             // ADC deaktivieren

Autor: Georg (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, hab ich so gemacht. An AREF messe ich jetzt dauerhaft 2,6V. Das 
sollte ja passen.

Autor: Georg (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bekomme immer noch Werte zwischen 350 und 380, egal welche Spannungen 
anliegen.

Gerade liegen vor dem 4k7 -3V an, nach dem 4k7 sind es noch -0.6V.

Wahrscheinlich ist der ADC auf grund der neg. Spannungen defekt?!

Hier im Forum wird aber öfter geschrieben, dass einen Absicherung nur 
mit einem Widerstand reicht (in Verbindung mit den internen Dioden). Ist 
das nicht zutreffend?

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die -0,6 Volt entstehen durch den Spannungsteiler:

-3Volt  Widerstand   -0,6Volt   Diode |>|  Masse

Daher passt das schon, du musst nur aufpassen, dass der Strom durch die 
Diode nicht größer als 1 mA wird, sonst ist sie kaputt und dein Eingang 
gleich mit.

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nachtrag: Diode natürlich andersrum :-)

Autor: Georg (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
jepp ... sollte ja nicht passieren.

(-4V + 0.6V) / 4k7 = 0.7 mA   (-4V ist der max. auftretende Wert).


Sollte also im grünen Bereich sein.


Gibt es eine Möglichkeit festzustellen, ob der ADC definitiv defekt ist 
(z.b. messtechnisch)?

Autor: Spezi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Bekomme immer noch Werte zwischen 350 und 380

Sind diese Werte denn konstant, oder schwanken sie?

Versuche es mal zum Testen mit AVcc als Referenz (REFS1 = 0, REFS0 = 1). 
Ändert sich der A/D Wert?

Autor: Georg (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nach der Änderung zeigen beide Eingänge 1023.

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Georg schrieb:
> Gibt es eine Möglichkeit festzustellen, ob der ADC definitiv defekt ist
> (z.b. messtechnisch)?

Die neueren ADCs können über ADMUX mit einem internen Vergleichswert 
belegt werden, z.B. 1,2 Volt.
Bei diesen Vergleichwerten weist du ja dann, was ungefähr rauskommen 
muss. Stimmts überein, funktioniert der AD-Umsetzer noch, dann liegen 
die Probleme entweder beim Verdrahten oder beim Sensor.

Autor: Spezi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Die neueren ADCs können über ADMUX mit einem internen Vergleichswert
> belegt werden, z.B. 1,2 Volt.

Beim Mega128 ist dies:

MUX4..0 = 11110 - ADC misst interne Referenz (1.1V)
MUX4..0 = 11111 - ADC misst GND (sollte A/D-Wert von Null ergeben)

Aber eigentlich kann es nicht sein, dass bei höherer Referenzspannung 
ein grösserer A/D-Wert herauskommt (wie du beschrieben hast) ...

Autor: Georg (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ohh nein, ich hab differential inputs (AD0, AD1) statt  ADC0 und ADC 1 
verwendet!

Autor: Georg (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
moment ...

Autor: Georg (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
AD0(External memory interface address and data bit 0)

mensch ... wie konnte das nur passieren.

Autor: Georg (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann man noch dümmer sein?


Sorry, dass ich eure Zeit verschwendet habe!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.