www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik mega8 - ADC im Free Run geht nicht


Autor: Fabian S. (jacky2k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich versuche grade den ADC des Atmega8 im FreeRun Modus zu betreiben, 
das will mir jedoch nicht so ganz gelingen. Also ich weiß nicht genau 
woran es liegt und wollte daher einfach mal wissen, ob ich den ADC so 
richtig benutze/initialisiere:

void ADC_init()
{
  ADMUX = 3; // channel 3
  ADMUX |= (1<<REFS0);  // vcc als ref verwenden
  ADCSRA = (1<<ADEN) | (1<<ADPS0) | (1<<ADPS1) | (0<<ADPS2) | (1<<ADFR); 
// 8x prescaler at 16Mhz crystal
}

uint16_t GetValue()
{
  return ADCW;
}

Ich weiß, der Prescaler ist sehr klein, muss aber sein ;) Laut 
Datenblatt geht das, es leidet halt nur die Qualität der Messungen, das 
ist aber nicht so schlimm.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Der ADC muss gestartet werden ->'ADSC'-Bit. Teiler 8 ist arg schnell. 
Mit 128 würdest du im grünen Bereich liegen.

MfG Spess

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Der ADC muss gestartet werden ->'ADSC'-Bit. Teiler 8 ist arg schnell.
>Mit 128 würdest du im grünen Bereich liegen.

Und man muss auf das Ergebnis warten.
Den Scheiss der da oben als Code angeboten wird
kann er sich an die Tapete nageln.

Autor: Fabian S. (jacky2k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dir ist klar, dass es um den Free Run Modus geht?!?!
Da muss ich wenn ich das Datenblatt richtig interpretiere auf nichts 
warten. Wenn doch würde es erklären warum es nicht geht.

When this bit is set (one) the ADC operates in Free Running mode. In 
this mode, the ADC samples and updates the Data Registers continuously. 
Clearing this bit (zero) will terminate Free Running mode.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Dir ist klar, dass es um den Free Run Modus geht?!?!
>Da muss ich wenn ich das Datenblatt richtig interpretiere auf nichts
>warten. Wenn doch würde es erklären warum es nicht geht.

Selbstverständlich musst du auf das Ende einer Conversation warten. 
Woher willst du wissen, wann ein gültiges Ergebnis vorliegt? So wie du 
dir das vorstellst, ist Würfeln wesentlich genauer.

MfG Spess

Autor: Hannes Lux (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn das Einlesen eines Analog-Signals nicht besonders eilig ist, dann 
nutze ich auch gern den Free-Run-Mode. Allerdings lese ich das Ergebnis 
dann nebenher im Timer-Interrupt oder einem vom Timer-Interrupt 
synchronisierten Job aus, so dass zwischen den Ausleseterminen eine oder 
mehrere ADC-Wandlungen stattgefunden haben. Dazu ist es natürlich 
erforderlich, mal zu überschlagen, wie lange ein Wandlungszyklus dauert, 
was mit einem Taschenrechner und dem Verständnis der Zusammenhänge kein 
Problem ist.

Achja, der Timer wird nicht wegen des ADC gestartet, das ADC-Timing 
macht er nur nebenbei. Bei mir hat fast jedes AVR-Programm einen Timer 
laufen, der einen Großteil der Jobs synchronisiert und damit das 
Programm effizienter macht, indem man Warteschleifen und Busywaits 
vermeidet.

...

Autor: freeRunMode (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
du musst nicht zwangsläufig darauf warten, ob die Wandlung abgeschlossen 
ist oder nicht. Falls sie es nicht ist, liest du halt den Wert aus, der 
ein paar µs alt ist, wenn es auf die paar µs nicht ankommt, entsteht 
dadurch kein Problem.

Autor: Fabian S. (jacky2k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
freeRunMode wrote:
> Hallo,
> du musst nicht zwangsläufig darauf warten, ob die Wandlung abgeschlossen
> ist oder nicht. Falls sie es nicht ist, liest du halt den Wert aus, der
> ein paar µs alt ist, wenn es auf die paar µs nicht ankommt, entsteht
> dadurch kein Problem.

Jo, so hatte ich das auch verstanden und das ist auch voll OK. Das 
Problem ist, dass ich einen relativ schnellen Timer laufen habe (80kHz) 
der auf keinen Fall unterbrochen werden darf, also fällt der 
Interrupt-Vektor flach. Außerdem sollte auf eine Messung (die ruhig 
etwas älter sein darf) nicht lange gewartet werden müssen.
Also ist der obere Code zusammen mit dem Start Befehl OK?

Autor: Hannes Lux (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was hindert Dich daran, in der Mainloop das Interrupt-Pending-Flag zu 
pollen und bei noch nicht fertigem ADC das Auslesen und Auswerten zu 
überspringen und dafür andere Jobs zu erledigen?

...

Autor: Fabian S. (jacky2k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nichts, ist auch eigentlich egal. Aber wann wir das Flag denn gesetzt?? 
Ich meine der Free Run Modus ist ja grade, dass er die ganze Zeit am 
arbeiten ist, also wird das Flag mal in einem einzelnen System Takt 
gesetzt oder wie???

Autor: Fabian S. (jacky2k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe grade noch eine Erkenntnis gewonnen.
Das mit dem Warten auf das Flag hilft auch nichts! Weil von dem Ende der 
Schleife bis zum nächsten Takt wo ich den Wert dann auslese kann er ja 
auch verändert werden, passiert zwar nur seeehhhhhhhhr selten (ca einer 
von 6500), darf aber nicht passieren.

Gibt es evtl ne Möglichkeit Interrupts zu priorisieren, dass ich sagen 
kann sollte ein Timer Interrupt in der Warteschleife stehtn wird der auf 
jeden Fall als erster ausgelöst?

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Fabian S. wrote:
> Nichts, ist auch eigentlich egal. Aber wann wir das Flag denn gesetzt??
Wenn der ADC fertig ist und ein neues Ergebnis im Datenregister steht 
(letzteres allerdings unter der Voraussetzung, dass das Datenregister 
nicht durch einen falschen oder unvollständigen Zugriff blockiert ist, 
siehe AVR 16-Bit-Register)...

> Ich meine der Free Run Modus ist ja grade, dass er die ganze Zeit am
> arbeiten ist, also wird das Flag mal in einem einzelnen System Takt
> gesetzt oder wie???
Schau bitte ins Datenblatt! Da steht, wie lange der ADC für eine 
Wandlung braucht. Und das ist erheblich mehr als ein Systemtakt!

Autor: Fabian S. (jacky2k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wir reden doch hier von dem ADIF Wert oder???

Autor: Spocki (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Das
>Problem ist, dass ich einen relativ schnellen Timer
>laufen habe (80kHz) der auf keinen Fall unterbrochen
>werden darf, also fällt der Interrupt-Vektor flach.

???

Ein Timer-Overflow-Interrupt hält doch den Timer nicht an.
In der TOVL-Interruptroutine kannst Du dann eine Variable zählen und 
diese regelmässig aus der main abfragen.

Wo ist das Problem?

Autor: Fabian S. (jacky2k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das habe ich auch nie gesagt!
Der ADC Interrupt hält evtl den Timer Interrupt auf! Und das darf nicht 
passieren.

Autor: Hannes Lux (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Der ADC Interrupt hält evtl den Timer Interrupt auf! Und das darf nicht
> passieren.

Das passiert auch nicht, wenn Du den ADC in der Mainloop ausliest.

Die Mainloop ist ja, wie der Name schon sagt, eine Schleife. In dieser 
wird ADIF abgefragt. Ist es gesetzt, dann ist eine Wandlung fertig. Dann 
kannst Du:
- ADCL und ADCH auslesen (da wird ein temporäres Hilfsregister aktiv,
  um das zu verhindern, was Du befürchtest, das ist aber im Datenblatt
  bestens erklärt)
- ADIF durch Schreiben einer 1 löschen
- den ausgelesenen ADC-Wert wegräumen bzw. auswerten

Falls ADIF nicht gesetzt war, überspringst Du einfach diesen Block.

Wo also ist Dein Problem??? Dein Timer schlägt (bei 16MHz Quarz) alle 
200 Takte zu. Wenn die ISR halbwegs effizient programmiert ist, bleibt 
für die Mainloop massig Zeit für verschiedene Jobs.

Es gibt auch noch die Möglichkeit, aus der Timer-ISR langsamere Takte 
abzuleiten. Man kann in der Timer-ISR z.B. ein Register herunterzählen. 
In der Mainloop fragt man das Register auf größer Startwert ab (das wäre 
ein Unterlauf), setzt es auf Startwert und arbeitet den Job ab. Das 
kostet in der ISR einen einzigen zusätzlichen Takt und bläht die 
Mainloop auch nicht unnötig auf. Bei einem Startwert von 79 entsteht 
dabei in Deinem Fall ein Jobtakt von 1kHz. Dies ist eine gute Basis für 
ADC lesen, Drehgeber abfragen, LCD bedienen, mit weiterem Teiler 1:16 
Tasten entprellen, Berechnungen anschubsen, usw. Ein Timer kann nämlich 
bei guter Programmplanung etliche Arbeiten zugleich erledigen bzw. 
synchronisieren.

...

Autor: Fabian S. (jacky2k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mhh da hab ich wohl was verplant. Man muss warten bis das Bit gesetzt 
ist, dann ist er fertig und um es zu resetten muss man es wieder setzen? 
Ist es dann nicht immer auf 1?

Autor: Hannes Lux (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> und um es zu resetten muss man es wieder setzen?

Ja, so ist es...

Mecker' nicht herum, lies und verstehe stattdessen das verdammte 
Dartenblatt!!!

...

Autor: Fabian S. (jacky2k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja ich habe meinen Fehler doch eingeräumt, dass ich mich in der einen 
Zeile im Datenblatt verlesen habe, wo steht, dass man es setzen und 
nicht löschen muss.

> Mecker' nicht herum, lies und verstehe stattdessen das verdammte
> Dartenblatt!!!
Und du kannst mich wohl kaum dazu auffordern etwas zu verstehen, wenn 
ich bitten darf. Entwerder ich verstehe es oder nicht, wenn nicht und 
ich hier desshalb was frage ist das wohl berechtigt.

Autor: Ahem (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man mag einräumen, das Hannes Lux Aufforderung ein wenig harsch klingt, 
aber sie ist nicht ohne Anlass geblieben. (Das Du gemeckert hast finde 
ich nicht).

Ganz offensichtlich verstehst Du nicht irgendein Detail nicht, sondern:

1. Du weisst nicht, das AD-Wandlung gestartet werden muss -> Datenblatt
2. Du weisst nicht, das auf den Abschluss der Wandlung gewartet werden 
muss bzw. das es dafür einen Interrupt gibt. -> Datenblatt
3. Du weisst nicht, das auch im Free-Run-Modus nicht einfach Ergebnisse 
erzeugt werden -> Datenblatt
4. sondern das auch dort die Wandlung abgewartet werden muss -> 
Datenblatt
5. Du weisst nicht wie der Free-Run-Mode überhaupt geht -> Datenblatt
6. Du weisst nichts über die Wandlungsgeschwindigkeit -> Datenblatt
7. Du weisst nichts über Interruptprioritäten im AVR -> Datenblatt
8. Du weisst nicht das man die Prioritäten nicht verändern kann -> 
Datenblatt (zugegeben, das muss man daraus schliessen, das eine 
Möglichkeit dazu nicht angegeben ist.)

Das heisst Dir fehlen die meisten Grundlagen für die AD-Wandlung und die 
Interruptbehandlung.

Es ist ja nicht schlimm, das Du das alles nicht weisst. Aber ich finde 
es unhöflich von Dir zu erwarten, das wir Dir hier alles ohne eigene 
Anstrengung servieren und das wir hier Dein Halbwissen und Deine 
Vermutungen bestätigen oder widerlegen.

Also lies BITTE das f... Manual und die Tutorials und stelle dann fragen 
die sich auf gelesenes und ausprobiertes beziehen.

Autor: Hannes Lux (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke...

...

Autor: Fabian S. (jacky2k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ahem wrote:
> Man mag einräumen, das Hannes Lux Aufforderung ein wenig harsch klingt,
> aber sie ist nicht ohne Anlass geblieben. (Das Du gemeckert hast finde
> ich nicht).
>
> Ganz offensichtlich verstehst Du nicht irgendein Detail nicht, sondern:
>
> 1. Du weisst nicht, das AD-Wandlung gestartet werden muss -> Datenblatt
Weiß ich, hatte ich auch gesagt, dass ichs nur vergessen hatte mit rein 
zu schreiben
> 2. Du weisst nicht, das auf den Abschluss der Wandlung gewartet werden
Und desshalb meine Frage, ob das was ich als aller erstes gepostet hatte 
korrekt ist. Wo auch das auslesen eines Wertes drin steht. Und ich habe 
im Datenblatt nichts gefunden, was aussagte, dass im Free Run Modus 
jemals ein ungültiger Wert in dem Register steht.
> muss bzw. das es dafür einen Interrupt gibt. -> Datenblatt
Ich hatte auch gesagt, dass ich den Interrupt nicht verwenden will/kann.
> 3. Du weisst nicht, das auch im Free-Run-Modus nicht einfach Ergebnisse
> erzeugt werden -> Datenblatt
Wie gesagt, habe ich eben nicht gefunden (habe ich auch immer noch 
nicht)
> 4. sondern das auch dort die Wandlung abgewartet werden muss ->
> Datenblatt
> 5. Du weisst nicht wie der Free-Run-Mode überhaupt geht -> Datenblatt
> 6. Du weisst nichts über die Wandlungsgeschwindigkeit -> Datenblatt
Wieso? Eigentlich schon? ADC Takt durch den Faktor (den ich bei der 
Initialisierung ja auch eingestellt habe und das auch begründet habe) 
und dann dauert eine Wandlung 13 Takte oder so.
> 7. Du weisst nichts über Interruptprioritäten im AVR -> Datenblatt
> 8. Du weisst nicht das man die Prioritäten nicht verändern kann ->
> Datenblatt (zugegeben, das muss man daraus schliessen, das eine
> Möglichkeit dazu nicht angegeben ist.)
Da hast Recht, werde ich mir mal ansehen.

Autor: Hannes Lux (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, das erinnert mich an:
Youtube-Video "Ein Loch ist im Eimer"
;-)

...

Autor: Ahem (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Seufz.

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.