AnsweredAssumed Answered

STM32F0 Scan ADC Polling Sequence

Question asked by botha.antonie on Apr 11, 2017
Latest reply on Aug 25, 2017 by Frank Sanders

Good Day

 

Please help me understand if I am using the Polling Mode correctly for the ADC. I have not gone through the trouble of setting up DMA or Interrupts because these functions will hardly ever be used in my system. 

 

I have set up the ADC to convert 4 Channels for me, Channel 1, Channel5, VREFINT and Temperature sensor, like this: 

void MX_ADC_Init(void)
{
  ADC_ChannelConfTypeDef sConfig;

    /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
    */

  hadc.Instance = ADC1;
  hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
  hadc.Init.Resolution = ADC_RESOLUTION_12B;
  hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
  hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc.Init.LowPowerAutoWait = DISABLE;
  hadc.Init.LowPowerAutoPowerOff = DISABLE;
  hadc.Init.ContinuousConvMode = DISABLE; //AJ 10Apr changed from ENabled
     
  hadc.Init.DiscontinuousConvMode = DISABLE;
  hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc.Init.DMAContinuousRequests = DISABLE;
  hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  if (HAL_ADC_Init(&hadc) != HAL_OK)
  {
    Error_Handler();
  }

    /**Configure for the selected ADC regular channel to be converted. */
  sConfig.Channel = ADC_CHANNEL_1;
     sConfig.Rank = 1;
  sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5; // See AN3116
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
     sConfig.Channel = ADC_CHANNEL_VREFINT;     /* Get 3V3 Volt reading from this */
     sConfig.Rank = 2;
     sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
     if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
          sConfig.Channel = ADC_CHANNEL_5; /* 5V Div to 2.5V */
     sConfig.Rank = 3;
     sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
     if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
     sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
     sConfig.Rank = 4;
     sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
     if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
     
     HAL_ADCEx_Calibration_Start(&hadc); // Calibrate

}

After starting the ADC, it is my understanding that I need to Poll for a conversion and then go and read the result, which will be the result for Rank1, and then poll again and read the result, which should be Rank 2, and poll again and read and the result should be for Rank3, and then poll one more time to read the result for Rank 4, and then calling to stop the ADC. Next time I start it, it will restart from Rank1. Is this correct? I am not getting the expected values for Ranks 2, 3 and 4, though the result for Rank1 seems to be correct. 

HAL_ADC_Start(&hadc);
uint16_t ADCValue = 0x00;
uint16_t MCUTemperatureDegrees = 0;
if (HAL_ADC_PollForConversion(&hadc, HAL_MAX_DELAY) == HAL_OK)
{
        ADCValue = HAL_ADC_GetValue(&hadc); /* Gets CH1 */
        HAL_ADC_PollForConversion(&hadc, HAL_MAX_DELAY);
        ADCValue = HAL_ADC_GetValue(&hadc); /* Gets 3V3 */
     HAL_ADC_PollForConversion(&hadc, HAL_MAX_DELAY);
     ADCValue = HAL_ADC_GetValue(&hadc); /* Gets 5V */
     HAL_ADC_PollForConversion(&hadc, HAL_MAX_DELAY);
     ADCValue = HAL_ADC_GetValue(&hadc); /* Gets Temp */
}                              
HAL_ADC_Stop(&hadc);
MCUTemperatureDegrees = __LL_ADC_CALC_TEMPERATURE(3300, ADCValue, LL_ADC_RESOLUTION_12B);

 

Appreciate any help,  I know I really should convert this to using DMA but I do not currently have time and this section is low-priority. 

 

Kind Regards

Outcomes