Hallo zusammen,
ich versuche gerade die best mögliche Genauigkeit aus dem ADC eines
Nucleo-F072RB (STM32F072) zu bekommen. Hintergrund ist, dass ich eine
Eingangsspannung nach einem Spannungsteiler messen möchte. Wenn dabei
schon der angenommene/ermittelte Wert der Referenzspannung für die
Berechnung falsch ist, passt natürlich der gemessene Wert nicht, schon
gar nicht nach dem Spannungsteiler.
Daher hatte ich versucht den ADC mit den intern gespeicherten Werten der
Referenzspannung zu kalibrieren. Zum Einen durch die
Selbstkalibrierungsroutine, zum Anderen durch die Ermittlung der
tatsächlich anliegende Spannung an VDDA, welche für die weiteren
Messungen als Referenzwert genutzt wird.
Leider komme ich bereits bei dieser Ermittlung auch eine Differenz von
etwa 15 mV. Mit zwei kalibrierten Multimetern und einem Oszi messe ich
(direkt an den uC Pins 12 und 13 ) stabile 3.310 V mit etwa 5 mVpp
Ripple und keine Einbrüche während den Messungen. Direkt an den VDDA-
und GNDA-Pins habe ich 2x10nF, 1x 100nF und 1x10uF KerKos versucht und
kombiniert. Die Messung und Berechnung vom STM32 ergibt stabile ~3.296 V
(+-1 LSB), also 14 mV Abweichung. Der ADC ist auf 12-Bit und die längste
Samplerate von 239 Cycles eingestellt.
Hat schon jemand ein ähnliches Problem gehabt und bestenfalls gelöst?
Anbei die wichtigen Ausschnitte aus meinem Code zur Kalibrierung:
1
// ADC self calibration, has to be done before any ADC Start/Enable
pegel schrieb:> Chris schrieb:>> stabile 3.310 V>> Aber in deinen Berechnungen benutzt du 3,30V !?
Die 3.3 V ist der Referenzwert von ST (VRefInt @3.3V/30°C). Durch das
Verhältnis aus den im Werk gespeicherten Wert in VREFINT_CAL (Register
0x1FFFF7BA) und den vom ADC eingelesenen Wert VREFINT_DATA (bzw.
adc_value[2]) lässt sich dann auf die aktuell tatsächlich anliegende
VDDA schließen.
Bei solchen Sachen hacke ich das Ganze immer testweise in Excel (oder
LibreOffice Calc) ein. Dazu lasse ich mir im Debugger die Rohwerte des
ADCs ausgeben.
Bei C macht man gerne subtile Fehler in den Formeln - mit den
Zwischenergebnissen aus Excel findet man die recht schnell.
Beispielsweise könnte
1
330000*VREFINT_CAL
überlaufen - diese Multiplikation wäre nur mit dem 64-bittigem 330000ULL
sicher.
Netter Nebeneffekt: Man sieht auch sofort wenn der ADC außerhalb seines
Messbereichs betrieben wird, weil dann Null oder 4095 als Rohwert
auftaucht.
Das wird so nix werden. VDDA als Referenz ist nicht gut genug. Die
Idioten von ST haben bei diesem Teil keinen Vref Anschluss
herausgeführt. Vlt. die Interne Referenz verwenden und entsprechend
kalibrieren. Ich verwende den STM32F103Z im 144pol. Geh. und mit
externer Präzisionsreferenz von 2,5V.Da arbeitet der ADC schon aufs Bit
genau.
Grüsse
Es gibt Referenzspannungs-ICs, die 3.3V, 10mA liefern können. Damit
könnte man den VDDA/VREF-Pin versorgen. Bei der L4-Familie (jedenfalls
beim STM32L471) darf VDDA auch viel kleiner sein als VDD, bei den
älteren Chips darf die Differenz evt. nicht zu groß sein.
Marcus H. schrieb:> Wie siehst Du Deine Fragestellung vor dem Hintergrund des Datenblatts?> STM32F072xx datasheet rev5 Februar 2017
Gehe ich davon aus, dass bei jedem möglichem Fehler der Maximalwert
zutrifft, also insgesamt 10 LSB, dürfte man doch immernoch "nur" etwa 8
mV Fehler haben, oder denke ich falsch? ( (3.3 V / 4095) * 10 LSB = 8.06
mV).
Jim M. schrieb:> Beispielsweise könnte 330000 * VREFINT_CAL> überlaufen - diese Multiplikation wäre nur mit dem 64-bittigem 330000ULL> sicher.
VREFINT_CAL kann maximal den Wert 4095 haben, daher sollte das Ergebnis
in ein 32-bit unsigned int passen. Bei den restlichen Berechnungen wird
ein ausreichend großer Datentyp natürlich beachtet.
Geb schrieb:> Vlt. die Interne Referenz verwenden und entsprechend kalibrieren.
Die interne Referenz ist auch nicht wirklich genau (1.2 - 1.25 V). Daher
ist der Ansatz ja die Kalibrierung wie oben beschrieben. Wenn diese in
regelmäßigen Abständen durchgeführt wird, sollte auch eine sich (z.B.
durch Temperatur) ändernde VDDA-Spannung genutzt werden können.
Außerdem liegt das Problem ja nicht mal darin, dass diese Spannung in
irgend einer Art und Weise schwankt oder nicht stabil ist. Kann es sein
dass die intern gespeicherten Werte in VREFINT_CAL einfach falsch sind?
Also nicht nur um das letzte Bit, sondern deutlich mehr?
Chris schrieb:> Marcus H. schrieb:>> Wie siehst Du Deine Fragestellung vor dem Hintergrund des Datenblatts?>> STM32F072xx datasheet rev5 Februar 2017>> Gehe ich davon aus, dass bei jedem möglichem Fehler der Maximalwert> zutrifft, also insgesamt 10 LSB, dürfte man doch immernoch "nur" etwa 8> mV Fehler haben, oder denke ich falsch? ( (3.3 V / 4095) * 10 LSB = 8.06> mV).
Dann habe ich das "+-1 LSB" in Deinem Kommentar falsch interpretiert:
"Die Messung und Berechnung vom STM32 ergibt stabile ~3.296 V
(+-1 LSB), also 14 mV Abweichung."
ST gibt im Datenblatt als Werkskalibrierbedingung 3,3V+-10mV an. Das ist
das bestmögliche zu erwartende Ergebnis. Wenn Du es präziser brauchst,
musst Du in Deiner Applikation nachkalibieren.
Bei absoluten Genauigkeitsanforderungen jenseits 8bit würde ich zu einem
externen ADC raten.
Marcus H. schrieb:> Dann habe ich das "+-1 LSB" in Deinem Kommentar falsch interpretiert:> "Die Messung und Berechnung vom STM32 ergibt stabile ~3.296 V> (+-1 LSB), also 14 mV Abweichung."
Das war eigentlich so gemeint, dass die ADC Messung der internen
Referenzspannung einen Wert von 1529, 1530 oder 1531 liefert, also das
letzte Bit in seltenen Fällen hüpft, evtl durch die Erwärmung während
der Laufzeit.
Schade, ich hätte gehofft etwas präziser messen zu können da ich schon
von Genauigkeiten von +-1 mV gelesen habe, und dort auch keine externe
Referenzspannung verwendet wurde. Das waren dann aber vmtl nur
Glückstreffer oder es war doch eine externe und genaue Referenzspannung
im Einsatz.
Dennoch vielen Dank für die Hilfe
Chris schrieb:> Schade, ich hätte gehofft etwas präziser messen zu können da ich schon> von Genauigkeiten von +-1 mV gelesen habe, und dort auch keine externe> Referenzspannung verwendet wurde. Das waren dann aber vmtl nur> Glückstreffer oder es war doch eine externe und genaue Referenzspannung> im Einsatz.
Niemand hindert Dich daran einmalig einen genaueren Wert für die interne
Referenz als VREFINT_CAL mit einem guten Multimeter zu vermessen und im
Flash zu speichern.