I am new to ARM world and using STM32F103C8T6 ARM microcontroller. I want to get micro's internal temperature sensor working.
I am able to get some data from it but I'm not sure how to convert these numbers into temperature. I looked it up on and I found that there is two read-only addresses in memory that hold factory calibration numbers at 30 and 110 degrees.
The problem is there is nothing about it in either datasheet or Reference Manual. There is only some minimums and maximums for parameters. I believe using average of these values may affect accuracy. So I'm confused. How should I do this conversion? Do I even need these factory calibration data? Do I have to self calibrate the ADC in this case?
here is the code I used so far:
#include "stm32f103xb.h"
int main(void)
{
// Select a clock source for ADC
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; // Enable ADC1 to use APB2 BUS
RCC->CR |= RCC_CR_HSION; // set the internal clock on (8MHz)
while((RCC->CR & RCC_CR_HSIRDY) == 0){} // wait until HSI is ready
RCC->CFGR &= ~(RCC_CFGR_HPRE); // set AHB prescaler to 1
RCC->CFGR &= ~(RCC_CFGR_PPRE2); // set APB2 prescaler to 1 (PCLK2)
RCC->CFGR |= RCC_CFGR_ADCPRE; // use ADC prescaler
// Select a Sampling rate
ADC1->SMPR1 |= ADC_SMPR1_SMP16;
ADC1->SQR3 |= ADC_SQR3_SQ1_4; //set to convert the channel 16 fitst
// enable temperature sensor
ADC1->CR2 |= ADC_CR2_TSVREFE;
// ADC Calibration
// Power up the ADC and then Calibrate it
ADC1->CR2 |= ADC_CR2_ADON | ADC_CR2_CAL | ADC_CR2_CONT;
// wait until the calibration is completed and reseted
while((ADC1->CR2 & ADC_CR2_CAL) == 1){}
while(1)
{
// Start
ADC1->CR2 |= ADC_CR2_ADON;
while((ADC1->SR & ADC_SR_EOC) == 0){} // wait for end of conversion
// Print the results on LCD
LCDSendInstruction(LCD_CLEAR);
LCDSendInteger(ADC1->DR,8);
}
}
Thanks in advance 😀
Best Answer
The STM32Cube library for your part includes one or two helper macros for calculating the temperature from an ADC reading of the internal temperature sensor. The User Manual for the HAL and Low-layer (LL) Drivers describes these macros. The implementation differs from one STM32 family to another so make sure you get the information for your particular part. Even if you're not going to use the STM32Cube library you can still refer to the source code for an example of how the temperature macros are implemented.
The two macros are
__LL_ADC_CALC_TEMPERATURE
and__LL_ADC_CALC_TEMPERATURE_TYP_PARAMS
.Some STM32 parts have temperature calibration values that are measured during manufacturing of the device and programmed into ROM. These parts use the
__LL_ADC_CALC_TEMPERATURE
macro. This macro uses the ROM calibration values to improve the accuracy of the temperature measurement.Other STM32 parts do not have temperature calibration values in ROM. These parts use the
__LL_ADC_CALC_TEMPERATURE_TYP_PARAMS
macro. This macro uses the "typical" values forAvg_Slope
andV25
taken from the device datasheet.I believe the STM32F1 family does not have temperature calibration values in ROM so you would use
__LL_ADC_CALC_TEMPERATURE_TYP_PARAMS
with the typical parameters from the device datasheet.If you want to improve the temperature readings you could calibrate each of your units during production and store the custom calibration values for
Avg_Slope
andV25
in ROM. Then substitute your custom calibration values for the typical values from the datasheet.