A/D Wandler Problem

Gast #126796
Ich möchte folgendes machen:
Ich frage über den USART bei einem MEGA8 nacheinander die Analogen
Eingänge ab. Das heisst ich dem uC zB. eine '0' und der uC schickt
mir zB. '1023' zurück. Das funktioniert auch soweit.
Jetzt das Problem:

Ich frage den uC über ein Programm permanent ab. Komischerweise scheint
die Spannung alle 5s zusammenzubrechen und sich dann wieder zu erholen
obwohl ich die Spannung am Analogeingang konstant halte.
Zuerst dachte ich das der USART Interrupt den AD Wandler unterbricht
und deshal dieser seltsame Effekt auftritt. Aber auch nachdem ich das
uC Programm so geändert habe, dass bei Empfang eines Bytes der USART
Interrupt abgeschaltet wird und erst nach dem Senden der Antwort wieder
angeschaltet wird, ändert sich nichts. Ich bin etwas ratlos. Könnte das
ein elektrischer Fehler sein ?
Gast
Wenn jetzt einer kommt und dir erzählt, daß der Fehler in Zeile 43
liege, dann will er darauf hinweisen, daß ohne Sourcecode hier wenig zu
sagen ist...

----, (QuadDash).
Gast
Ja OK ich habs kapiert !

Also USART empfängt Byte....

if (data == '1')
  {
  USART_Pause();
  ADMUX =  _BV(MUX0);
  ADCSRA =  _BV(ADEN) | _BV(ADPS2) |  _BV(ADIE);          ADCSRA |=
_BV(ADSC);
  }
Wenn der ADC fertig ist...

SIGNAL (SIG_ADC) {

  ADCSRA = 0x00; //BV(ADIE) | BV(ADEN);
  ADMUX = 0x00;
  x = ADC;
  itoa(x, buffer, 10);
  USART_transmit_string (buffer);
  USART_Weiter();


}

hier nochmal die Funktionen Pause und Weiter:

void USART_Pause(void)
{
UCSRB = BV(RXCIE) | BV(TXCIE) | _BV(RXEN) | _BV(TXEN);
}

void USART_Weiter(void)
{
UCSRB = _BV(RXCIE) | _BV(TXCIE) | _BV(RXEN) | _BV(TXEN);
}
Gast
@hannes

ich denke schon, ich wähle die Quelle und aktiviere dann den
ADC-Interrupt. Das Auslesen kommt dann ja erst wenn der Interrupt da
ist. (siehe Quellcode oben)
Gast
@hannes
Wieso nicht ?
ADMUX ist doch nur für die Auswahl des ADC Kanals und das Klappt. Nur
wenn ich immer wieder alle Kanäle nacheinander auslese kommt es alle 5s
zu Problemen. Es klappt also ca. 10-20 mal nacheinander bevor es
schiefgeht.
Aber falls das trotzdem der Fehler ist, wie mache ich es richtig ?

mfg

Heinz
Gast
Richtig...

Und im Interrupt setzt du zuerst ADMUX auf 0 und liest erst danach den
ADC aus.

  ADMUX = 0x00;
  x = ADC;

Das kann gut gehen, muss aber nicht.
Ich würde ADMUX erst ändern, wenn ein neuer "Messauftrag" vorliegt.

Oder noch besser alle ADC-Quellen reiherum ausmessen und die Werte im
SRAM speichern. Wenn UART einen Wert anfordert, dann diesen aus dem
SRAM holen...

...HanneS...
Gast
Also ich hab das mal abgeändert und ADMUX aus dem Interrupt
herausgenommen sieht dann so aus:

if (data == '2')
  {
  USART_Pause();
  ADMUX = 0x00;
  ADMUX =   _BV(MUX1);
  ADCSRA =  _BV(ADEN) | _BV(ADPS2) |  _BV(ADIE);    //ADC-Interrupt
aktivieren (ADIE)

  ADCSRA |= _BV(ADSC);
  }


SIGNAL (SIG_ADC) {

  ADCSRA = 0x00; //BV(ADIE) | BV(ADEN);
  x = ADC;
  itoa(x, buffer, 10);                      //wandelt (int) in string um
  USART_transmit_string (buffer);
  USART_Weiter();
}

ich habs auch gleich getestet, ist aber immer noch dasselbe Problem
Gast
Was hat es denn mit diesem Prescaler auf sich ?
Laut Datenblatt soll die Eingangsfrequenz zwischen 50kHz und 200 kHz
liegen. Meine liegt bei 62,5 kHz. Wäre eine höhere Frequenz besser ?
Gast
Danke für die vielen Tips !
Ich konnte das Problem inzwischen lösen. Falls jemand dasselbe Problem
hat:
Es lag nicht an der Software, sondern an meinem (zu billigen) Netzteil
mit dem ich hier arbeite. Offensichtlich kann der ADC mit
Wechselspannungsanteilen in der zu messenden Spannung nicht besonders
gut umgehen. Ein Kondensator zwischen  ADCx und GND und schon
funtionierts.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 21 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.