ADC Auslesen STM32F04

#7743862
Lesenswert?

Hallo,

ich kämpfe seit Tagen damit,Temperaturwerte aus einem ADC vom STM32 auszulesen. Ich habe DMA und polling versucht und jedes mal sind die Werte total unplausibel. Wenn ich mit einem multimeter Messe sehen die Werte aber plausibel aus.

Hat jemand das schonmal gemacht und den Beispielcode für mich?

#7743886
Lesenswert?

Patrick E. schrieb:

Ich habe DMA und polling versucht

Dann zeig Mal den Code dazu. Ohne kann hier niemand weiter helfen.

Patrick E. schrieb:

und jedes mal sind die Werte total unplausibel.

Wie äußert sich das? Wie sehen die Werte aus und was erwartest du?

Patrick E. schrieb:

Wenn ich mit einem multimeter Messe sehen die Werte aber plausibel aus.

Wieso, was misst du damit?

Patrick E. schrieb:

Hat jemand das schonmal gemacht und den Beispielcode für mich?

Etwas unspezifisch. Zum einen gibt es von ST selbst einige Beispiele. Zum anderen ist das mit Arduino eine Zeile. Also was genau willst du?

#7743938
Lesenswert?

Ich habe alles soweit schon ausprobiert, im Moment sieht es so aus:

https://dpaste.org/7m6zr https://dpaste.org/DymS9

Wenn ich das richtig verstehe, kann man bei den kleinen STM32 die "Scan conversation mode" nicht ausschalten und muss daher immer alle konfigurierten ADC Sensoren in einem rutsch pollen. Deshalb sollte man lieber DMA benutzen, man sieht auch noch schnippsel von dem DMA code in dem source code, diese werden zur Zeit nicht benutzt.

Die Beispiele kenne ich auch, die rufen da aber nur einen ADC ab, wenn ich micht nicht täusche.

Ich habe auch meine clock config mal angehängt.

Angehängte Dateien:
Gast #7743964
Lesenswert?

Patrick E. schrieb:

Also du meinst ich sollte den Spannungsteiler lieber auf 1k / 100R reduzieren? Kann ich mit meinen 10k NTCs kann überhaupt was anfangen?...

Die Impedanz des Spannungsteilers entspricht der Parallelschaltung beider Widerstände.

1k / 100R ergäben 91 Ohm

10k / 10k ergeben 5k Ohm

Bis 10k bin ich sicher, dass das ohne Probleme funktionieren kann. Denn niemand zwingt dich dazu, eine besonders kurze Sampling-Zeit einzustellen.

Siehe file:///home/stefan/Downloads/an2834-how-to-optimize-the-adc-accuracy-in-the-stm32-mcus-stmicroelectronics.pdf Kapitel 3.2.7 und 4.2.6

Gast #7743972
Lesenswert?

Oliver R. schrieb:

Schon wieder jemand, der lokale Files verlinkt.

Oh, das hatte ich per Google gefunden und aus der URL Zeile kopiert, ohne genau hin zu schauen.

https://www.st.com/resource/en/application_note/an2834-how-to-optimize-the-adc-accuracy-in-the-stm32-mcus-stmicroelectronics.pdf

Noch eine Ergänzung:

Man kann mit einem Oszilloskop am Eingang des ADC messen, wie stark er den Spannungsteiler belastet.

Man kann ggf. diese Spannung mit externen Kondensatoren (zwischen Signal und GND) stabilisieren. Wenn der externe Kondensator relativ groß ist (z.B. 100nF) und zwischen den Messungen reichlich Zeit zum Aufladen bekommt, dann ergibt sich eine schön stabile Spannung. Ganz egal wie hochohmig der Spannungsteiler ist.

#7744017
Lesenswert?

Monk schrieb:

...

Man kann ggf. diese Spannung mit externen Kondensatoren (zwischen Signal und GND) stabilisieren. Wenn der externe Kondensator relativ groß ist (z.B. 100nF) und zwischen den Messungen reichlich Zeit zum Aufladen bekommt, dann ergibt sich eine schön stabile Spannung. Ganz egal wie hochohmig der Spannungsteiler ist.

Jepp. 100n vor den Pin auf dem geteilten Signal sollte auch gehen. Eine Akkuspannung muss man ja nicht 1000x pro Sekunde einlesen. Da kann man auch 1x in der Sekunden den ADC einmal messen lassen.

Auf der Seite 107 in https://www.st.com/resource/en/datasheet/stm32f401re.pdf ist die berechnung für die Eingangsimpedanz der ADC.

Ich habe mir aus den Erfahrungen gemerkt, dass alles über 5k Quellimpedanz extrem ungenau wird. Die in den electrical Spec angegbenen 50k (max) sind reines Wunschdenken am theoretischen Rand des ADC...

#7744108
Lesenswert?

Monk schrieb:

Patrick E. schrieb:

Sampling rate ist auf Maximum trotzdem springen die Werte zwischen 0 und 4095. Gemessen habe ich am spannungsteiler 0,2xxx Volt also sollte ich doch ca 248 am ADC auslesen.

Also wahrscheinlich ein Softwareproblem.

Mit dma kommt auch nur 0 zurück. Sollte ich mal von HAL auf LL umschalten in cubemx? Ich habe jetzt so ziemlich alle Kombinationen durch und weiß auch nicht mehr weiter wie ich da sinnvolle werte raus bekommen soll.

Gast #7744117
Lesenswert?

Patrick E. schrieb:

Sollte ich mal von HAL auf LL umschalten in cubemx?

Ich bin kein Fan von der HAL, aber ich bin sicher, dass die Problemursache woanders liegt. Lerne lieber, sie richtig zu benutzen. Dazu reicht die Doku der HAL alleine nicht aus. Man muss auch das Reference Manual und das Datasheet dazu lesen.

Vielleicht erst mal mit einem STM32F0 oder L0 anfangen, denn die sind weniger komplex.

#7744131
Lesenswert?

Patrick E. schrieb:

Wenn ich das richtig verstehe, kann man bei den kleinen STM32 die "Scan conversation mode" nicht ausschalten und muss daher immer alle konfigurierten ADC Sensoren in einem rutsch pollen.

Nein, hast du nicht.

STM32F0x Reference Manual:

Analog input channels: – 16 external analog inputs – 1 channel for internal temperature sensor (V SENSE ) – 1 channel for internal reference voltage (V REFINT ) – 1 channel for monitoring external V BAT power supply pin

Start-of-conversion can be initiated: – By software – By hardware triggers with configurable polarity (timer events)

Conversion modes: – Can convert a single channel or can scan a sequence of channels. – Single mode converts selected inputs once per trigger – Continuous mode converts selected inputs continuously – Discontinuous mode

Persönliche Seite #7744148
Lesenswert?

Patrick E. schrieb:

Die Beispiele kenne ich auch, die rufen da aber nur einen ADC ab, wenn ich micht nicht täusche.

Dann fang doch erstmal damit an. Wenn das Beispiel einen Kanal korrekt abfragt kannst du es erweitern. Man kann bei solchen Themen so viel falsch machen, da ist es absolut sinnvoll mit einem funktionierenden(!) Beispiel anzufangen anstatt Ewigkeiten an einem vermurksten Code herumzudoktorn. Und wenn es doch ein Hardware-Problem ist, kannst du lange an der Software herumpfuschen.

#7744156
Lesenswert?

Patrick E. schrieb:

Die Beispiele kenne ich auch, die rufen da aber nur einen ADC ab, wenn ich micht nicht täusche.

Der STM32F04xx hat nur einen einzigen ADC. Der jeweilige Messkanal wird durch einen Multiplexer auf dessen Eingang gelegt (Neudeutsch "geroutet").

Per DMA kann man eine vorher festgelegte Reihenfolge der Messkabnäle festlegen, die ziemlich wahlfrei ist (ich kene das Reference Manual des F04 nicht [auswendig]).

Mit STCubeMX kann man das alles fertig konfigurieren,

#7744659
Lesenswert?

Patrick E. schrieb:

Mit dma kommt auch nur 0 zurück. Sollte ich mal von HAL auf LL umschalten in cubemx? Ich habe jetzt so ziemlich alle Kombinationen durch und weiß auch nicht mehr weiter wie ich da sinnvolle werte raus bekommen soll.

Da würd' ich doch glatt mal alle ADC- und DMA-Register "zu Fuß" auslesen und kontrollieren, ob da wirklich das Gewünschte drin steht ...

#7744772
Lesenswert?

Norbert schrieb:

Niklas G. schrieb:

Das DMA speichert aber wahrscheinlich einzelne 16bit-Werte in diesen Puffer. Wenn man diese in C als 32bit ausliest passiert Murks.

Patrick E. schrieb:

trotzdem springen die Werte zwischen 0 und 4095.

Lässt sich jedoch nicht mit falscher DMA Übertragungsgröße (WORD/HALFWORD) erklären.

Ich hatte HALFWORD/HALFWORD konfiguriert... Was aber natürlich Murks ist. Ich habe jetzt, weil RAM hab ich ja, auf WORD/WORD umgestellt und siehe da. Es klappt... plausible Werte..

Wirklich vielen vielen Dank! Und ich werde mir für die nächste Schaltung merken, dass ich die ADC Eingangswiderstände überprüfe und die Eingänge puffer.

#7744783
Lesenswert?

Patrick E. schrieb:

Ich hatte HALFWORD/HALFWORD konfiguriert... Was aber natürlich Murks ist. Ich habe jetzt, weil RAM hab ich ja, auf WORD/WORD umgestellt und siehe da. Es klappt... plausible Werte..

WORD sind in dieser Architektur 32bit und somit gänzlich unnötig bei ADC. HALFWORD sind 16 bit und das ist korrekt, wenn man damit ein uint16 array füllt. Oftmals kann man sogar (bei verminderter Auflösung) den ADC auf 8bit setzen (autoshift >> 4) und mit DMA BYTE Transfers ein uint8 array füllen.

#7744821
Lesenswert?

Norbert schrieb:

Patrick E. schrieb:

Ich hatte HALFWORD/HALFWORD konfiguriert... Was aber natürlich Murks ist. Ich habe jetzt, weil RAM hab ich ja, auf WORD/WORD umgestellt und siehe da. Es klappt... plausible Werte..

WORD sind in dieser Architektur 32bit und somit gänzlich unnötig bei ADC. HALFWORD sind 16 bit und das ist korrekt, wenn man damit ein uint16 array füllt. Oftmals kann man sogar (bei verminderter Auflösung) den ADC auf 8bit setzen (autoshift >> 4) und mit DMA BYTE Transfers ein uint8 array füllen.

Richtig wäre dann ja trotzdem WORD -> HALFWORD ... Ich hatte nicht verstanden das es hier um peripherie Breite --> Memory Breite ging.

#7744826
Lesenswert?

Patrick E. schrieb:

Richtig wäre dann ja trotzdem WORD -> HALFWORD ... Ich hatte nicht verstanden das es hier um peripherie Breite --> Memory Breite ging.

Ähm, nein.

Datenblatt STM32F0: 13.11.9 ADC data register (ADC_DR) Address offset: 0x40 Reset value: 0x0000 0000 Bits 15:0 DATA[15:0]: Converted data

Also DMA read: HALFWORD (nimmt automagisch den unteren 16bit Teil) DMA write: HALFWORD

Edit: N.M. war schneller

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren