www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ADC Code


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

Bewertung
0 lesenswert
nicht lesenswert
Hallo alle zusammen,

ich möchte am PIN 3 des Ports A einen analogen Wert zyklisch mit dem
AD-Wandler einlesen.
Dazu habe ich das Programm wie im Anhang geschrieben.
Da meine Hardware noch nicht vorhanden ist, Teste ich im AVR Studio.
Nun meine Frage, ist der Code prinzipiell richtig, da ich in der AVR
Simulation ja nicht wirklich das Auslesen des AD-Pins testen kann, weiß
ich nicht, ob der Code so zyklisch ausliest?
Oder habe ich einen denkfehler?

Danke für eure Antworten schon mal.

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

Bewertung
0 lesenswert
nicht lesenswert
Sollte eigentlich funktionieren. Ich häng' Dir mal meine Funktionen
dran die funktionieren definitiv, über die Handhabung einer Addition
bei vorzeichenbehafteten Zahlen kann man anderer Meinung sein,
funktioniert hier aber. Die Funktion wird mit ADMUX-Einstellung und
Anzahl Mittelwerte aufgerufen. Jeweils einmal für single-ended und
differentielle Messung.

Autor: Thilo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach ja.. hatte ich vergessen: die Einstellugen (Prescaler usw.) werden
bei mir ausserhalb dieser Funktionen aufgerufen.

Autor: Marcus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wo setzt du,

welchen AD-PIN du ausliest?
WO setzt d MW?

Funktoniert überhaupt eine Simulation im AVR Studio?

Autor: Thilo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein Aufruf würde so aussehen:

Messergebnis = ADC_conversion (2,32);

Würde bedeuten dass ADMUX mit 2 (=> ADC2, siehe Datenblatt) und 32 für
32 Messwerte zum mitteln gesetzt würde.
Der Rückgabewert der Funktion steht dann in 'Messergebnis'
Sofern Du den GNU-Compiler (hier WinAVR) benutzt sollte es auch im
AVR-Studio funktionieren.

Autor: Marcus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
so langsam durchschaue ich es langsam,

danke schon mal für die Tips,
werde morgen gleich noch mal probieren, bei Problemen gibt es ja zum
Glück ds Forum, danke noch mal

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Abgesehen davon, dass es nicht sonderlich sinnvoll ist, eine übergebene
Variable (in diesem Falle channel) in der Funktion sofort wieder zu
überschreiben, könnte das ganze funktionieren.

Kleiner Tip: Bei einer Mittelwertbildung wenn möglich immer Potenzen
von 2 als Anzahl der Messwerte nehmen. Das schon Ressourcen, da das
Programm dadurch kleiner und schneller wird, weil sich Divisionen durch
2^n durch einfache Bitschiebeoperationen ersetzen lassen. Nimm also
(vorausgesetzt, das ist möglich) lieber 4 Messwerte für den Mittelwert
anstatt 3.

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OT...

Mittelwert von Messungen mache ich meist über 256 Messungen, denn dann
kann man die Division durch Byteschieben realisieren, was sehr
effizienten Code ergibt:

;====================================================================
; Routine für Mittelwert über 256 Messungen (z.B. ADC)
;--------------------------------------------------------------------
; in 'wert_h' und 'wert_l' steht der Mittelwert,
; in 'wert_n' sind die Nachkommastellen, wl und wh sind
Temp-Register
; das Register 'null' enthält immer 0

;für 16-Bit-Werte:
 in wl,adcl             ;ADC-Wert
 in wh,adch             ;einlesen
 sub wert_n,wert_l      ;1/256 vom Wert
 sbc wert_l,wert_h      ;mit Übertrag
 sbc wert_h,null        ;subtrahieren,
 add wert_n,wl          ;1/256 des neuen
 adc wert_l,wh          ;Wertes mit Übertrag
 adc wert_h,null        ;addieren
;fertig...

;für 8-Bit-Wert:
 in wl,adch             ;linksbündig justierten ADC-Wert einlesen
 sub wert_n,wert        ;1/256 vom alten Wert
 sbc wert,null          ;mit Übertrag subtrahieren
 add wert_n,wl          ;1/256 vom neuen Wert
 adc wert,null          ;mit Übertrag addieren
;fertig...

...

Autor: Thilo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In meiner Lösung habe ich absichtlich eine double-Variable gewählt, da
die Anzahl der Aufzusummierenden Werte sonst begrenzt (Überlauf), oder
durch mehr Rechenaufwand zu realisieren ist. Außerdem habe ich bei
bitweiser Division am Ende immer noch die 5mV-Sprünge (Uref 5V). Bei
Atmel auf de HP gibt's Beispiele für einen 'Quasi-16-Bit-ADC'.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
double ist auf dem AVR auch nicht größer als float. Ein 32bit-Integer
hat mehr Genauigkeit als eine float-Variable.
Und was den Rechenaufwand betrifft, so sind Fließkommaberechnungen auf
einem Prozessor ohne FPU um ein Vielfaches aufwendiger, als die
Integerberechnungen, selbst wenn man diese mit 64 bits macht.

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.