ADC temperature dependence. Broken or defective?
Our company has developed a thermostat based on a microcontroller STM8L151K4T6. Many thermostats from the manufacturer were rejected. The analysis showed that the microcontroller does not correctly measure the voltage at the external terminals. The measured voltage is highly dependent on the temperature of the microcontroller.
For example: + 20С - ADC_DR = 0x07A6, and +50C - ADC_DR = 0x0600 (at supply voltage 3.2В).
A change in temperature has almost no effect on the measurement of the internal voltage reference.
After replacing the microcontroller with a new one everything comes back to normal and the temperature does not affect the measurement.
Init
/* High speed internal clock prescaler: 1 */
CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_1);
/* Select HSE as system clock source */
CLK_SYSCLKSourceSwitchCmd(ENABLE);
CLK_SYSCLKSourceConfig(CLK_SYSCLKSource_HSI);
CLK_LSEConfig(CLK_LSE_ON);
/* Wait for LSE clock to be ready */
while (CLK_GetFlagStatus(CLK_FLAG_LSERDY) == RESET);
/* wait for 1 second for the LSE Stabilisation */
LSE_StabTime();
/* Select LSE (32.768 KHz) as RTC clock source */
CLK_RTCClockConfig(CLK_RTCCLKSource_LSE, CLK_RTCCLKDiv_1);
void init_ADC(void)
{
CLK_PeripheralClockConfig(CLK_Peripheral_ADC1, ENABLE);
ADC_DeInit(ADC1);
ADC_Cmd(ADC1, ENABLE);
ADC_Init(ADC1, ADC_ConversionMode_Single, ADC_Resolution_12Bit, ADC_Prescaler_2);
ADC_DMACmd(ADC1, DISABLE);
CLK_PeripheralClockConfig(CLK_Peripheral_DMA1, DISABLE);
ADC_VrefintCmd(ENABLE);
ADC_TempSensorCmd(DISABLE);
ADC_SchmittTriggerConfig(ADC1, ADC_Channel_0, DISABLE);
ADC_SchmittTriggerConfig(ADC1, ADC_Channel_1, DISABLE);
ADC_SchmittTriggerConfig(ADC1, ADC_Channel_2, DISABLE);
ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);
ADC_SamplingTimeConfig(ADC1, ADC_Group_SlowChannels, ADC_SamplingTime_96Cycles);
ADC_SamplingTimeConfig(ADC1, ADC_Group_FastChannels, ADC_SamplingTime_96Cycles);
ADC_AnalogWatchdogConfig(ADC1, ADC_AnalogWatchdogSelection_Vrefint, ((uint16_t)(((unsigned long int) 3000)*(0x600 + Factory_VREFINT)/U_CPU_POWER_MIN)), (uint16_t)1305);
return;
}
