Skip to main content
Denis Gottardello
Associate III
March 3, 2017
Question

stm32, adc, temperature and vbat

  • March 3, 2017
  • 6 replies
  • 1909 views
Posted on March 03, 2017 at 11:16

Hi. I'm a beginner with adc and internal voltage - temperature sensor.

I can't get the right values using HAL_ADC_GetValue. The program goes to freeze using the HAL_ADC_PollForConversion function. Can someone show me the right code to get the internal temperature value?

Regards.
    This topic has been closed for replies.

    6 replies

    waclawek.jan
    Super User
    March 3, 2017
    Posted on March 03, 2017 at 23:01

    I don't Cube, but surely there is a complete example for ADC readout in it?

    Start from that, and if it works switch the input channel to the temperature sensor's one.

    JW

    T J
    Senior III
    March 4, 2017
    Posted on March 04, 2017 at 01:05

    I use CubeMX to initialise all the ADC channels..

    I use a 2 dimensional table to collate the results for oversampling.

    16 rows of data and 15 channels of ADC's, the VBat VRef, Temp are the last three in the table...

    when the row counter gets to 16, you can sum all the columns for 16bit ADC results...

    to start it, before while(1);

    HAL_ADC_Start_DMA (&hadc,(uint32_t *)ADC_DMABuffer,ADC_Channels);

    the DMA Interrupt,

    extern 'C' void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc){
    
     if(! ADC_ChannelsCounter--){ ADC_ChannelsCounter = ADC_Channels ;
     HAL_ADC_CompleteCycle = true; // signal foreground to process // copy 15 results away now for (int i=0;i<ADC_Channels;i++){ //here add 2nd dimension to the array HAL_ADC_Channel_Buffer [ADC_RowCounter][i] = ADC_DMABuffer[i]; // AVEColumnSum += HAL_ADC_Channel_Buffer [Ave_ADC_RowCounter][Ave_ADC_ChannelCounter]; }
     ADC_RowCounter ++; // for next time through the loop if ( ADC_RowCounter == ADC_RowCount) ADC_RowCounter =0; }}�?�?�?�?�?�?�?�?
    ADC_HandleTypeDef hadc;DMA_HandleTypeDef hdma_adc;
    /* ADC init function */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_SEQ_CONV; hadc.Init.LowPowerAutoWait = DISABLE; hadc.Init.LowPowerAutoPowerOff = DISABLE; hadc.Init.ContinuousConvMode = DISABLE; hadc.Init.DiscontinuousConvMode = ENABLE; hadc.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T15_TRGO; hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISINGFALLING; hadc.Init.DMAContinuousRequests = ENABLE; hadc.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; if (HAL_ADC_Init(&hadc) != HAL_OK) { Error_Handler(); }
     /**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_0; sConfig.Rank = ADC_RANK_CHANNEL_NUMBER; sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
     /**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_1; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
     /**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_2; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
     /**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_3; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
     /**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_6; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
     /**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_7; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
     /**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_8; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
     /**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_9; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
     /**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_10; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
     /**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_11; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
     /**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_13; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
     /**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_14; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
     /**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_15; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
     /**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_TEMPSENSOR; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
     /**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_VREFINT; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
     /**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_VBAT; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
    }�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

    S.Ma
    Principal
    March 4, 2017
    Posted on March 04, 2017 at 17:03

    In an effort to step back from daily routine programming, I explored a different coding style where the SW library would contain the datasheet (or CubeMX) in the C source itself.

    This also enables application engineers to express their STM32 needs using application terms, reducing the need to look for spec details.

    Here is an extract of the code for ADC peripheral. Consider it as a pseudo code. Maybe you'll find what's missing in it... or not.

    ________________

    Attachments :

    Adc.c.zip : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HyrA&d=%2Fa%2F0X0000000bDB%2FoPYJbBHs6BhfFKlmoTzj0UEfY8ib9r9p4rRkwisCxUg&asPdf=false

    Adc.h.zip : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HyeX&d=%2Fa%2F0X0000000bD9%2FwPqbKBvCEE1eUe5.mQF2jad0mkk32G41O8oLniG4DG8&asPdf=false
    Philippe Cherbonnel
    ST Employee
    April 13, 2017
    Posted on April 13, 2017 at 10:09

    Hi Denis,

    What is your STM32 serie ?

    For example, in the case of STM32L4, you can find some examples in

    STM32L4 FW package (can be downloaded here:

    /external-link.jspa?url=http%3A%2F%2Fwww.st.com%2Fen%2Fembedded-software%2Fstm32cubel4.html

    ).

    You can find an example here:

    Using driver HAL:

    STM32Cube_FW_L4_V1.7.0\Projects\STM32L496ZG-Nucleo\Examples\ADC\ADC_Sequencer\

    Using driver LL:

    STM32Cube_FW_L4_V1.7.0\Projects\STM32L476RG-Nucleo\Examples_LL\ADC\ADC_MultiChannelSingleConversion\

    This example shows how to:

    - Measure ADC internal channels VrefInt and temperature sensor (channel Vbat can also be added easily)

    - Convert ADC raw conversion data into physical value: VrefInt in mV, temperature in degree Celcius.

    Additionally, it shows how to calculate board voltage Vref+ (connected to Vdda is most of the case).

    Denis Gottardello
    Associate III
    May 30, 2017
    Posted on May 30, 2017 at 16:11

    Many thanks.

    Nesrine M_O
    Associate
    May 30, 2017
    Posted on May 30, 2017 at 16:42

    https://community.st.com/0D50X00009bMM5DSAW