stm32adcstm32cubeidenucleo

HAL_ADC_PollForConversion - what exactly is it for?


I've been tinkering around STM32 (F103RB) for a couple of weeks now and one thing I don't get is

HAL_ADC_PollForConversion

function purpose. I mean, I don't see any impact of this function on ADC readings. Here's my code example:

   Version 1 (with PollForConversion on)

     while (1)
    
    {
        HAL_ADC_Start(&hadc1);
        HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
         
        uint32_t value = HAL_ADC_GetValue(&hadc1);
        float voltage = 3.3f * value / 4096.0f;
         
        printf("ADC = %lu (%.3f V)\n", value, voltage); //send the value via UART
        HAL_Delay(250);
    
        }

Version 2 (with PollForConvertion off)

     while (1)
    
    {
        HAL_ADC_Start(&hadc1);
        //HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
         
        uint32_t value = HAL_ADC_GetValue(&hadc1);
        float voltage = 3.3f * value / 4096.0f;
         
        printf("ADC = %lu (%.3f V)\n", value, voltage); //send the value via UART
        HAL_Delay(250);
    
        }

As far as my observations go, it doesn't really matter whether I use PollForConversion or not - the readings on the UART monitor look the same (altough I am not 100% certain they actually are the same). Continous mode is disabled. What am I missing here?


Solution

  • After you start ADC with HAL_ADC_Start(), hardware starts ADC conversion. This conversion takes some time. Exact time depends on your ADC configuration in Cube, the greater value of ADC prescaler and cycle count the longer it takes.

    After conversion is completed, EOC flag in ADC hardware is set and measured value is placed in register. You can read that value with HAL_ADC_GetValue() function. But if you read it before end of conversion, you will probably get data that is corrupted or an old value from previous measurement.

    That's why you should always wait untill EOC flag is set - this is exactly what HAL_ADC_PollForConversion does.

    In your example without polling you probably read value from previous measurement before the current one ended. Or maybe HAL functions that interact with hardware are slow enough to actually read data when EOC flag is set anyway. You can increase number of ADC clock cycles in Cube to maximum and try it then, you should get a value from last measurement.