Estoy jugando con una placa Nucleo-F103RB STM32 y estoy tratando de medir la temperatura ambiente usando su sensor interno. Activo el ADC y obtengo datos normalmente a través de la HAL_ADC_GetValue()
función (el valor es de alrededor de 1700 - 1800 y varía con la temperatura como debería) pero el problema es que obtengo números realmente extraños cuando convierto a Celsius usando la fórmula dada en el manual, a saber :
Sospecho que tiene que ver con la forma en que estoy convirtiendo el valor de ADC en voltios, pero no puedo ver algo obviamente incorrecto, así que vine a preguntar aquí.
El código está aquí:
#include "TempMsr.h"
volatile uint32_t sensorData = 0;
volatile uint32_t temp = 0;
uint32_t getTemp(ADC_HandleTypeDef* ADCHandle)
{
sensorData = HAL_ADC_GetValue(ADCHandle);
temp = ((V25 * 1000 - sensorData * 0.8) / AVGSLOPE) + 25;
//V25 and sensorData must be in mV for this formula to work, as the
//AVGSLOPE value is given in mV/oC
//the 0.8 multiplication comes from dividing the max ADC voltage (3.3V) with its resolution (12 bits => 4096) which is 0.8mV/ADC unit
return temp;
}
Su archivo de cabecera:
#ifndef TEMPMSR_H_
#define TEMPMSR_H_
#include "stm32f1xx_hal.h"
#define AVGSLOPE 4.3
//average slope of T-V chart according to datasheet pg 79
//(min is 4 mV/C, max 4.6, default (4.3): typical)
#define V25 1.43
//voltage of temperature sensor at 25C according to datasheet pg 79 (in V)
//(min is 1.34, max is 1.52, default(1.43): typical)
uint32_t getTemp(ADC_HandleTypeDef* ADCHandle);
#endif /* TEMPMSR_H_ */
¡Gracias de antemano!
EDITAR: Acabo de notar en el manual de referencia que el sensor tiene un sesgo (de hasta +- 45 grados) debido al proceso de fabricación, que es diferente en cada chip y no lo calculé para mi MCU particular ni lo incluí en la formula. ¿Podría ser este el problema?
No soy experto en C, tal vez
Tienes que analizar uint para flotar, luego calcular, luego analizar nuevamente para uint, si el resultado tiene que ser uint.
{
sensorData = HAL_ADC_GetValue(ADCHandle);
temp = (uint32_t)(((V25 * 1000.0 - (float)sensorData * 0.8) / AVGSLOPE) + 25.0);
//V25 and sensorData must be in mV for this formula to work, as the
//AVGSLOPE value is given in mV/oC
//the 0.8 multiplication comes from dividing the max ADC voltage (3.3V) with its resolution (12 bits => 4096) which is 0.8mV/ADC unit
return temp;
}
Habiendo realizado la detección de temperatura en un STM32 anteriormente, tengo una razón para creer que la fórmula es incorrecta, mientras que una documentación anterior de STM32F207 tenía la fórmula correcta.
Como la pendiente es positiva, las medidas más grandes (valor ADC o voltaje) significan una temperatura más alta. Entonces la fórmula debería tener (Vadc-V25), no (V25-Vadc).
Aún así, su punto sobre las compensaciones es válido. La medición V25 tiene una tolerancia de +/- 90 mV que calcula una tolerancia de aproximadamente +/- 21 grados centígrados. La documentación de ST ha indicado que no es preciso para medir temperaturas absolutas sin calibración, mientras que puede usarse para rastrear cambios de temperatura. En la práctica, ha sido lo suficientemente preciso sin calibración para controlar un ventilador para evitar que un producto se sobrecaliente.
Un sensor de temperatura en el chip no va a medir la temperatura del aire ambiente, va a medir la temperatura del chip del que forma parte. Un sensor de temperatura integrado en un microcontrolador mide la temperatura del microcontrolador, que debería ser significativamente más alta que la temperatura del aire ambiente si el microcontrolador está haciendo algún trabajo.
En STM32F0 y STM32L4 con los que estamos trabajando en este momento, el sensor de temperatura interno está precalibrado durante la producción y también se puede calibrar durante el tiempo de ejecución con la referencia de voltaje interno.
El cálculo de la temperatura también es diferente del valor adc normal al cálculo del voltaje porque incluye los valores de calibración.
Tal vez su controlador tenga la misma característica. La descripción debe estar disponible en el capítulo ADC en el Manual de referencia. Diría que la resolución en nuestra aplicación es de +/- 1 grado.
Marko Bursic
punto de luz21
Lundin