www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AD-Wandlung dauert zu lange (30µs) [Atmega32]


Autor: Funkenschlosser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich lasse den AD-Wandler frei laufen, da eine single conversion zu lange 
dauert. Eine 20 kHz PWM stößt bei der steigenden Flanke ein Interrupt an 
(Timer1 Overflow ist die steigende Flanke) und in diesem Interrupt wird 
der AD-Wandler enabled.

Um zu erkennen, wie lange die Wandlung dauert, wird ein Port 
eingeschaltet und nach der Wandlung wieder ausgeschaltet. Mit dem 
Oszilloskop messe ich 30µs, was bei einer Periodendauer der PWM von 50µs 
viel zu lange ist, da ich während den Flanken nicht messen will, um 
Einflüsse zu vermeiden. Die PWM ist im Betrieb die größte Zeit fast voll 
aufgefahren. Wie erreicht man die im Datenblatt angegebenen 7µs?

ISR(TIMER1_OVF_vect) //Wird bei pos. PWM-Flanke ausgeführt
{
   PORTC |= (1<<PC0); // Pin high für Zeitmessung des ADC´s am Oszi
   ADCSRA |= (1<<ADEN); //ADC enable
   ADCSRA |= (1<<ADSC); //ADC starten
}

ISR(ADC_vect)
{  
    UIST = ADCW; // Wert holen
    ADCSRA &=  ~(1<<ADEN); // ADC deaktivieren
  
    PORTC &= ~(1<<PC0);  // Pin low, Zeitmessung ende
    messen = TRUE; // Berechnung freischalten
}

main:
{
....
ADMUX = 4; // Kanal waehlen
ADMUX |= (1<<REFS0); // interne Referenzspannung nutzen
ADCSRA |= (1<<ADATE)| (1<<ADIE) | (1<<ADPS2) | (0<<ADPS1); // 250 kHz
ADCSRA |= (1<<ADSC); 

sei();

...

Autor: Sinusgeek (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der ADC soll mit 50kHz bis 200kHz getaktet werden.

Eine Wandlung in der schnellsten Betriebsart (im Free-Run-Mode ohne 
Quellenumschaltung) dauert 13 ADC-Takte

Das sind 65µs im günstigsten Fall.

Wenn ich es richtig verstanden habe (C ist nicht mein Ding) nutzt Du 
aber nicht den Free-Run-Mode, sondern den Auto-Trigger-Mode (per Timer), 
wodurch weitere Verzögerungen entstehen.

Zusätzlich schaltest Du die Messquelle um (ADMUX), das erfordert eine 
Erstmessung, die 26 ADC-Takte dauert oder (bei Free-Run) das Verwerfen 
des ersten Messwertes.

Was erwartest Du eigentlich, wenn Dir 30µs schon zuviel sind?

~

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Wie erreicht man die im Datenblatt angegebenen 7µs?

Welches Datenblatt?

MfG Spess

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ADC-Takt 250kHz sind bei mir 4µs pro Takt.
Eine Wandlung dauert 13 Takte macht also 52µs.
Da Du den ADC unsinnigerweise auch noch jedesmal erst einschaltest, 
braucht die Wandlung als erste Wandlung sogar 25 Takte, also 100µs.

Atmel gibt 13-260µs Wandlungszeit im Datenblatt an.
13µs ergibt dann aber höchstens noch 6-7 Bits nutzbare Auflösung.
Ich weiß also nicht so recht, wo Deine Werte herkommen.

Gruß aus Berlin
Michael

Autor: Sinusgeek (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das mit der Umschaltung der Mess-Quelle nehme ich zurück, da habe ich 
mich verguckt... - Sorry

~

Autor: Funkenschlosser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das erste Beispiel war ein Schnellschuß. Ich habe den Wandler immer 
wieder aktiviert/deaktiviert. Jetzt mache ich es so, dass ich den 
ADC-Interrupt erst bei der steigender Flanke freischalte, kurz warte und 
dann den Wert hole. Der Wandler läuft dauernd.

ISR(TIMER1_OVF_vect) //steigende Flanke
{
   TCNT2 = 200; //Timer2 vorladen (Overflow bei 255)
   TIFR  |= (1<<TOV2); //alte Overflows löschen
   TIMSK |= (1<<TOIE2); //Timer2 Interrupt aktvieren
}

ISR(TIMER2_OVF_vect) //Overflow kommt ca. 5µs nach steigender PWM-Flanke
{
   PORTC |= (1<<PC0); //Zeit messen am Oszi
   ADCSRA|= (1<<ADIE); //AD-Wandler Interrupt aktivieren
   TIMSK &= ~(1<<TOIE2); //Timer2 Interrupt löschen, nicht mehr benötigt
}

ISR(ADC_vect)
{  
    UIST = ADCW;
    ADCSRA &=  ~(1<<ADIE); //AD-Overflow löschen, nicht mehr benötigt
    PORTC &= ~(1<<PC0); //Messung Ende

    berechnen = TRUE;
}

main()
{
 ....
 //Timer1-PWM 20 kHz = 50µs Periodendauer

 TCCR2 |= (1<<CS20); //Timer2 (8bit) mit CPU-Takt

 ADMUX = 4;                      // Kanal waehlen
 ADMUX |= (1<<REFS0); // interne Referenzspannung nutzen
 // ADC aktivieren, Teiler 64 -> 250 kHz, Free-Running
 ADCSRA |= (1<<ADEN)|(1<<ADATE)|(1<<ADSC)|(1<<ADPS2)|(0<<ADPS1); 

 ....
 //berechnen etc.
}

Ich bin jetzt bei gemessenen 12µs inkl. setzen der Flags. Das sieht 
schonmal besser aus, damit kann ich leben und das ist auch das was im 
Datenblatt steht (13µs). Allerdings sehe ich beim Debuggen, dass die 
AD-Werte noch wesentlich öfter kommen. Alle paar CPU-Takte steht ein 
neuer AD-Wert im ADC. Dann bezieht sich die Angabe im Datenblatt also 
auf die gesamte Zeit, bis man einen AD-Wert geholt hat und ihn in einer 
Variable speichert zur weiteren Verarbeitung? Die eigentlich 
Sample&Hold-Wandlung geht wohl wesentlich schneller als das Abholen der 
Werte aus dem Register? Eigentlich müsste es bei 250 kHz mindestens 4µs 
dauern? Das wäre ja ein AD-Wert pro 64 CPU-Takte.

@ Was erwartest Du eigentlich, wenn Dir 30µs schon zuviel sind?

Der Atmega ersetzt einen 9 Jahre alten HC12, bei dem die single 
conversion laut Oszi-Messung auch nicht mehr als 10µ dauert. Da habe ich 
vom Mega32 schon etwas mehr erwartet. Es muss hier sehr schnell gehen, 
da die PWM eine große Leistung schaltet und ich das Messen während den 
Schaltvorgängen vermeiden will.

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.