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?
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.
Die Eingangsimpedanz der ADC schwankt stark mit der Einlesegeschwindigkeit. So hochohmig wie deine Messchaltung ist, solltest du so langsam wie sinnvoll messen...
Die Eingangsimpedanz der ADC schwankt stark mit der
Einlesegeschwindigkeit. So hochohmig wie deine Messchaltung ist,
solltest du so langsam wie sinnvoll messen...
Also du meinst ich sollte den Spannungsteiler lieber auf 1k / 100R reduzieren? Kann ich mit meinen 10k NTCs kann überhaupt was anfangen?...
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.
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.
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...
Ich habe jetzt mal 100 nF vom signal zu Masse gelötet. 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... Ungefähr .
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.
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.
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.
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
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.
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,
Sampling rate ist auf Maximum trotzdem springen die Werte zwischen 0 und
4095.
Das weckt den Verdacht, dass du das ADC-Register zum falschen Zeitpunkt ausliest. Wo in deinem hier gezeigten Quellcode wird denn sichergestellt, dass in dem Register im Moment des Auslesens ein gültiger Wert steht?
12Bit. Ist aber unkritisch, das 16Bit-Register in einen 32Bit uint zu packen. RAM ist bei den Cortex billig, da muss man nicht wegen drei oder vier Byte rumgeizen. Rechnen tut der schließlich auch mit 32Bit...
Das DMA speichert aber wahrscheinlich einzelne 16bit-Werte in diesen
Puffer. Wenn man diese in C als 32bit ausliest passiert Murks.
Kann sein. Ich habe das nicht mehr so im Gedächtnis.
Wegen solcher Hinweise sollte man sich das Kapitel "ADC" und/oder "DMA" im Reference Manual angucken.
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 ...
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.
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.
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.