Forum: Mikrocontroller und Digitale Elektronik ADC Code


von Marcus (Gast)


Angehängte Dateien:

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.

von Thilo (Gast)


Angehängte Dateien:

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.

von Thilo (Gast)


Lesenswert?

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

von Marcus (Gast)


Lesenswert?

wo setzt du,

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

Funktoniert überhaupt eine Simulation im AVR Studio?

von Thilo (Gast)


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.

von Marcus (Gast)


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

von johnny.m (Gast)


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.

von Hannes L. (hannes)


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...

...

von Thilo (Gast)


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'.

von Rolf Magnus (Gast)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.