AnsweredAssumed Answered

Vbat and temperature monitoring problem STM32F303CB

Question asked by Serhii Shevchuk on Jun 21, 2017
Latest reply on Jul 18, 2017 by Daniel Kluge

Hello.

There was a problem with the operation of the ADC with built-in thermistor and VBAT voltage.
The value 4095 is always read.
Here is an example of code for reading voltage VBAT:

  /* Configure the ADC clock */
  RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div2);
 
  /* Enable ADC1 clock */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ADC12, ENABLE);
        
  /* Setup SysTick Timer for 1 µsec interrupts  */
  if (SysTick_Config(SystemCoreClock / 1000000))
  {
    /* Capture error */
    while (1)
    {}
  }
      
  ADC_StructInit(&ADC_InitStructure);

  /* Calibration procedure */
  ADC_VoltageRegulatorCmd(ADC1, ENABLE);
 
  /* Insert delay equal to 10 µs */
  Delay(10);
 
  ADC_SelectCalibrationMode(ADC1, ADC_CalibrationMode_Single);
  ADC_StartCalibration(ADC1);
 
  while(ADC_GetCalibrationStatus(ADC1) != RESET );
  calibration_value = ADC_GetCalibrationValue(ADC1);
 
  Delay(100);
     
  ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;                                                                    
  ADC_CommonInitStructure.ADC_Clock = ADC_Clock_AsynClkMode;                    
  ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;             
  ADC_CommonInitStructure.ADC_DMAMode = ADC_DMAMode_OneShot;                  
  ADC_CommonInitStructure.ADC_TwoSamplingDelay = 0;          
 
  ADC_CommonInit(ADC1, &ADC_CommonInitStructure);
 
  ADC_InitStructure.ADC_ContinuousConvMode = ADC_ContinuousConvMode_Disable;
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  ADC_InitStructure.ADC_ExternalTrigConvEvent = ADC_ExternalTrigConvEvent_0;         
  ADC_InitStructure.ADC_ExternalTrigEventEdge = ADC_ExternalTrigEventEdge_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_OverrunMode = ADC_OverrunMode_Disable;   
  ADC_InitStructure.ADC_AutoInjMode = ADC_AutoInjec_Disable;  
  ADC_InitStructure.ADC_NbrOfRegChannel = 1;
  ADC_Init(ADC1, &ADC_InitStructure);
     
  ADC_RegularChannelConfig(ADC1, ADC_Channel_Vbat, 1, ADC_SampleTime_7Cycles5);  
  ADC_VbatCmd(ADC1, ENABLE);
 
  /* Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE);
 
  /* wait for ADRDY */
  while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_RDY));
    
  /* Infinite loop */
  while (1)
  {
    ADC_StartConversion(ADC1);
    
    /* Test EOC flag */
    while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
    
    /* Get ADC1 converted data */
    ADC1ConvertedValue =ADC_GetConversionValue(ADC1);
    
    /* Compute the voltage */
    ADC1ConvertedVoltage = (ADC1ConvertedValue *3300)/0xFFF;    
    
    printf("ADC1ConvertedValue = %d\r\n",ADC1ConvertedValue);
  }

Reading the temperature sensor is similar, only the ADC channel selection differs:

ADC_RegularChannelConfig(ADC1, ADC_Channel_TempSensor, 1, ADC_SampleTime_7Cycles5);  
  ADC_TempSensorCmd(ADC1, ENABLE);

In both cases, the ADC returns a value of 4095.
What am I doing wrong?
In the attachment - the whole project:

adc_std_01.rar - VBAT measurement design

adc_std_02.rar - Temperature measurement project

adc_01.rar - A temperature measurement project assembled in CubeMX using HAL

adc_02.rar - VBAT measurement design, assembled in CubeMX using HAL

Thanks in advance.

Attachments

Outcomes