cancel
Showing results for 
Search instead for 
Did you mean: 

stm32, adc, temperature and vbat

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.
6 REPLIES 6
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
Lead
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(); }
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

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
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).

Posted on May 30, 2017 at 16:11

Many thanks.

Posted on May 30, 2017 at 16:42

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