Guten Morgen,
ich hab ein hartnäckiges Problem mit dem STM32-internen
Temperatursensor.
Dieser liefert kontinuierlich Werte, die ca 10°C zu hoch sind.
Meine Initialisierung:
/**Configure for the selected ADC regular channel to be converted.
40
*/
41
sConfig.Channel=ADC_CHANNEL_VREFINT;//Initialize VREFINT_CAL reference voltage
42
sConfig.Rank=ADC_RANK_CHANNEL_NUMBER;
43
if(HAL_ADC_ConfigChannel(&hadc,&sConfig)!=HAL_OK)
44
{
45
Error_Handler();
46
}
47
48
sConfig.Channel=ADC_CHANNEL_TEMPSENSOR;// Initialize the chip temperature sensor
49
sConfig.Rank=ADC_RANK_CHANNEL_NUMBER;
50
if(HAL_ADC_ConfigChannel(&hadc,&sConfig)!=HAL_OK)
51
{
52
Error_Handler();
53
}
54
55
HAL_ADCEx_EnableVREFINT();
56
HAL_ADCEx_EnableVREFINTTempSensor();
57
}
Zur Umrechnung der ADC-Werte hab ich die Code-Snippts aus dem Reference
Manual und auch aus Example-Projekten aus dem STM32Cube Repository für
die L0.
1
#define TEMP30_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FF8007A)) /* Internal temperature sensor, parameter TS_CAL1: TS ADC raw data acquired at a temperature of 30 DegC (+-5 DegC), VDDA = 3.3 V (+-10 mV). */
2
#define TEMP130_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FF8007E)) /* Internal temperature sensor, parameter TS_CAL2: TS ADC raw data acquired at a temperature of 130 DegC (+-5 DegC), VDDA = 3.3 V (+-10 mV). */
3
4
#define VDDA_APPLI ((uint32_t) 3300) /* Value of analog voltage supply Vdda (unit: mV) */
5
#define VDDA_TEMP_CAL ((uint32_t) 3000) /* Vdda value with which temperature sensor has been calibrated in production (+-10 mV). */
Eigentlich kann man doch da nicht viel falsch machen - statt 25°C
erhalte ich Werte, die rund 10°C höher sind.
Ich kann mir beim besten Willen nicht vorstellen, dass ich die
Temperatur meines µCs um 10°C falsch einschätze.
Mein ADC wird mit 3,3V bepowert - das ist aber in der Umrechnung von als
VDD_APPLI einberechnet.
ADC Kalibrierung kann es nicht sein, weil ich auch eine
Batterie-Spannungsmessung eingebaut hab, die auf 5mV genau misst.
Hat jemand ähnliche Probleme mal festgestellt?
Viele Grüße,
Mampf
*edit*: Die beiden Kalibrierwerte:
658 für 30°C bei 3,0Vadc entspricht 598 @ 3,3Vadc
931 für 130°C bei 3,0Vadc entspricht 846 @ 3,3Vadc
ADC hat gelesen: 612 bei 3,3Vadc
Das wären definitiv mehr als 30°C
m = (130-30)/(846-598) = 0,40322
t = 30 - 0,40322 * 598 = -211,12556
Temp = 612 * 0,40322 - 211,12556 = 35,645°C
Hmm, kann da keinen Fehler entdecken.
*edit2*: Die slope (über die Kalibrierwerte) ist außerhalb des
max-Wertes: 1,81mv/°C
Angegeben ist: 1,48 (min), 1,61 (typ), 1.75 (max).
Das ist ja seltsam ...
Das ist nicht die Umgebungstemperatur, sondern die Chip-Temperatur. Die
Eigenerwärmung ist da zu berücksichtigen. Bei einem G030 hatte ich vor
einiger Zeit das mal ausprobiert, da hatte ich so etwa 2 bis 3 Grad über
Raumtemperatur (im Halt!!!) (inkl. Kalibrierung). 10 Grad ist schon ein
wenig viel, aber je nach Last/Leistungsaufnahme kann das trotzdem
hinkommen.
"The temperature sensor can be used to measure the junction temperature
(T J ) of the device."
"junction", nicht "ambient"!
Für Messungen der Umgebungstemperatur ist der interne Sensor nur sehr
bedingt geeignet.
A. B. schrieb:> "The temperature sensor can be used to measure the junction temperature> (T J ) of the device.">> "junction", nicht "ambient"!>> Für Messungen der Umgebungstemperatur ist der interne Sensor nur sehr> bedingt geeignet.
Ups, okay - ja du hast recht!
Ich hab mal alles angehalten (GPIOs im Reset, Clock runtergefahren) und
hab jetzt 28°C statt 35°C.
Hmm - also nicht benutzbar als Umgebungstemperatur-Sensor.
Gut zu wissen.
Danke!
Ach ja, bei manchen "abgespeckten" Varianten ist im Datenblatt entweder
nur TS_CAL1 oder TS_CAL2 angegeben, so z. B. beim G030 (ggü. G031) und
L011 (ggu. L031). Das heißt möglicherweise, dass man sich auf eine
Zweipunktkalibrierung nicht verlassen kann/soll. Diese Unklarheit
geistert schon seit Jahren durch die RMe bzw. Datenblätter, aber ST
kümmert's anscheinend nicht.
Wie häufig misst Du?
Ich hatte das mal ausprobiert und desto häufiger ich gemessen hatte,
desto weiter ging die Temp hoch. Dagegen nach 10 Sekunden Pause war es
wieder realistisch.
Aber der interne ist echt nur ein Schätzeisen. Ich nehm normal kleine
NTCs in 0603 wenn ich eine Umgebungstemperatur brauche. Die sind billig,
klein und leicht auszuwerten.
Bei dieser Temperaturmessung über die "Bandgap"-Reference" wird die
(Dioden-)Schwellspannung bei verschiedenen Strömen gemessen und daraus
die Temperatur ermittelt. Die Ströme wird man sinnvoll erst während der
Messung einschalten und so steigt die lokale Erwärmung während der
Messung und häufige Messungen führen zu höheren Temperaturwerten.
Gerd E. schrieb:> Wie häufig misst Du?>> Ich hatte das mal ausprobiert und desto häufiger ich gemessen hatte,> desto weiter ging die Temp hoch. Dagegen nach 10 Sekunden Pause war es> wieder realistisch.
Jede Sekunde :) Oh ok, so ähnlich wie bei den DS18B20 dann, die sich
beim Messen auch selbst erwärmen.
>> Aber der interne ist echt nur ein Schätzeisen. Ich nehm normal kleine> NTCs in 0603 wenn ich eine Umgebungstemperatur brauche. Die sind billig,> klein und leicht auszuwerten.
Hast du da zufällig eine erprobte Schaltung mit C-Code-Stückchen, das du
teilen würdest?
Sowas würde ich doch dann echt in jeder zukünftigen Anwendung
standardmäßig auf die Platine bauen :)
Mampf F. schrieb:>> Aber der interne ist echt nur ein Schätzeisen. Ich nehm normal kleine>> NTCs in 0603 wenn ich eine Umgebungstemperatur brauche. Die sind billig,>> klein und leicht auszuwerten.>> Hast du da zufällig eine erprobte Schaltung mit C-Code-Stückchen, das du> teilen würdest?
Klar, kein Problem. Schaltung siehe Bild anbei.
Den Widerstand kann man etwas an den 25°C-Widerstand des NTC und die zu
erwartenden Temperaturwerte anpassen. Für gängige Raumtemperaturen
funktioniert ein 10K-NTC und 10K als Teiler bei mir bisher gut.
Das wäre einfacher Code zum Auswerten, hier für einen 12 Bit ADC und
einen Controller mit Floatingpoint:
1
float calculate_ntc_temp(unsigned int adcvalue, unsigned int res_25c, unsigned int beta_constant, unsigned int res_divide)
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