www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik A/D Wandler Problem


Autor: bruzzler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 ?

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

mit wieviel Mhz laeuft der Mega? Welchen Prescalerwert hast du fuer den
ADC?

Mfg

Dirk

Autor: bruzzler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Dirk

Precaler ist 16 (ADPS2 Bit gesetzt)

bei 1Mhz

Autor: ---- (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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).

Autor: bruzzler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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);
}

Autor: ...HanneS... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lässt du dem ADC zwischen Auswahl der Quelle (ADMUX) und Auslesen des
Resultats genug Zeitn zum Messen?

Autor: ...HanneS... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du änderst ADMUX direkt vor dem Auslesen, das kann nicht gehen...

Autor: bruzzler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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)

Autor: bruzzler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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

Autor: ...HanneS... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: bruzzler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: bruzzler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 ?

Autor: bruzzler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: ...HanneS... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na der ist bei mir selbstverständlich...
(außer, die Messquelle ist recht niederohmig...)

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.