cancel
Showing results for 
Search instead for 
Did you mean: 

How do i use HAL_ADC_ConfigChannel to read temperature sensor value in stm32f413 (and getting temperature instead of vbat)?

KPirs
Associate

Hi,

i generated HAL code with the latest version of stm32cubemx and the latest stm32f4 software package.

In the pinout configuration of stm32cubemx i checked the temperature channel, therefore the vbat is unchecked.

Using the function HAL_ADC_ConfigChannel of stm32f4xx_hal_adc.c to set the channels and corresponding ranks to read, i set for example the ADC_CHANNEL_TEMPSENSOR channel.

That channel is defined as channel 18 in stm32f4xx_hal_adc_ex.h:

#if defined(STM32F413xx) || defined(STM32F423xx)

#define ADC_CHANNEL_TEMPSENSOR ((uint32_t)ADC_CHANNEL_18)

#endif /* STM32F413xx || STM32F423xx */ ,

which corresponds to the reference manual.

The vbat channel is as well channel 18 due to reference manual and set in stm32f4xx_hal_adc.h:

#define ADC_CHANNEL_VBAT    ((uint32_t)ADC_CHANNEL_18)

If the vbate bit is now set in the CCR register of the ADC, channel18 outputs the vbat value instead of temperature.

In the function HAL_ADC_ConfigChannel now on input ADC_CHANNEL_TEMPSENSOR of the sConfig the software does not distinguish between ADC_CHANNEL_TEMPSENSOR and ADC_CHANNEL_VBAT as both are defined as ADC_CHANNEL_18. The vbate bit is therefore set and temperature not read, instead the vbat value:

HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef* hadc, ADC_ChannelConfTypeDef* sConfig)

{

 __IO uint32_t counter = 0U;

 ADC_Common_TypeDef *tmpADC_Common;

  

 /* Check the parameters */

 assert_param(IS_ADC_CHANNEL(sConfig->Channel));

 assert_param(IS_ADC_REGULAR_RANK(sConfig->Rank));

 assert_param(IS_ADC_SAMPLE_TIME(sConfig->SamplingTime));

  

 /* Process locked */

 __HAL_LOCK(hadc);

   

 /* if ADC_Channel_10 ... ADC_Channel_18 is selected */

 if (sConfig->Channel > ADC_CHANNEL_9)

 {

  /* Clear the old sample time */

  hadc->Instance->SMPR1 &= ~ADC_SMPR1(ADC_SMPR1_SMP10, sConfig->Channel);

   

  /* Set the new sample time */

  hadc->Instance->SMPR1 |= ADC_SMPR1(sConfig->SamplingTime, sConfig->Channel);

 }

 else /* ADC_Channel include in ADC_Channel_[0..9] */

 {

  /* Clear the old sample time */

  hadc->Instance->SMPR2 &= ~ADC_SMPR2(ADC_SMPR2_SMP0, sConfig->Channel);

   

  /* Set the new sample time */

  hadc->Instance->SMPR2 |= ADC_SMPR2(sConfig->SamplingTime, sConfig->Channel);

 }

  

 /* For Rank 1 to 6 */

 if (sConfig->Rank < 7U)

 {

  /* Clear the old SQx bits for the selected rank */

  hadc->Instance->SQR3 &= ~ADC_SQR3_RK(ADC_SQR3_SQ1, sConfig->Rank);

   

  /* Set the SQx bits for the selected rank */

  hadc->Instance->SQR3 |= ADC_SQR3_RK(sConfig->Channel, sConfig->Rank);

 }

 /* For Rank 7 to 12 */

 else if (sConfig->Rank < 13U)

 {

  /* Clear the old SQx bits for the selected rank */

  hadc->Instance->SQR2 &= ~ADC_SQR2_RK(ADC_SQR2_SQ7, sConfig->Rank);

   

  /* Set the SQx bits for the selected rank */

  hadc->Instance->SQR2 |= ADC_SQR2_RK(sConfig->Channel, sConfig->Rank);

 }

 /* For Rank 13 to 16 */

 else

 {

  /* Clear the old SQx bits for the selected rank */

  hadc->Instance->SQR1 &= ~ADC_SQR1_RK(ADC_SQR1_SQ13, sConfig->Rank);

   

  /* Set the SQx bits for the selected rank */

  hadc->Instance->SQR1 |= ADC_SQR1_RK(sConfig->Channel, sConfig->Rank);

 }

  /* Pointer to the common control register to which is belonging hadc  */

  /* (Depending on STM32F4 product, there may be up to 3 ADCs and 1 common */

  /* control register)                          */

  tmpADC_Common = ADC_COMMON_REGISTER(hadc);

 /* if ADC1 Channel_18 is selected enable VBAT Channel */

 if ((hadc->Instance == ADC1) && (sConfig->Channel == ADC_CHANNEL_VBAT))

 {

  /* Enable the VBAT channel*/

  tmpADC_Common->CCR |= ADC_CCR_VBATE;

 }

  

 /* if ADC1 Channel_16 or Channel_17 is selected enable TSVREFE Channel(Temperature sensor and VREFINT) */

 if ((hadc->Instance == ADC1) && ((sConfig->Channel == ADC_CHANNEL_TEMPSENSOR) || (sConfig->Channel == ADC_CHANNEL_VREFINT)))

 {

  /* Enable the TSVREFE channel*/

  tmpADC_Common->CCR |= ADC_CCR_TSVREFE;

   

  if((sConfig->Channel == ADC_CHANNEL_TEMPSENSOR))

  {

   /* Delay for temperature sensor stabilization time */

   /* Compute number of CPU cycles to wait for */

   counter = (ADC_TEMPSENSOR_DELAY_US * (SystemCoreClock / 1000000U));

   while(counter != 0U)

   {

    counter--;

   }

  }

 }

  

 /* Process unlocked */

 __HAL_UNLOCK(hadc);

  

 /* Return function status */

 return HAL_OK;

}

What am i missing? Is there any additional configuration i have to make somewhere?

Regards, Kjell Pirschel

0 REPLIES 0