cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F0 Scan ADC Polling Sequence

abotha
Associate III
Posted on April 11, 2017 at 09:41

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 callingto 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

#polling #adc #hal #stm32f0
1 ACCEPTED SOLUTION

Accepted Solutions
T J
Lead
Posted on April 11, 2017 at 16:02

my ADC_init has these different lines...

  hadc.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;

    /**Configure for the selected ADC regular channel to be converted.

    */

  sConfig.Channel = ADC_CHANNEL_1;

  sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;  // = (0x00001000U) 

  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_5;

  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)

  {

    Error_Handler();

  }

View solution in original post

6 REPLIES 6
Nesrine M_O
Lead II
Posted on April 11, 2017 at 11:43

Hi

Botha.Antonie

,

Try to have a look to this example under the STM32F0 firmware package, it may help you :

STM32Cube_FW_F0_V1.7.0\Projects\STM32F072B-Discovery\Examples\ADC\ADC_RegularConversion_Polling

This example describes how to use the ADC in Polling mode to convert data through the HAL API.

-Nesrine-

Posted on April 11, 2017 at 11:52

Hi

ELMHIRI.Syrine

‌,

I have looked at that example,it unfortunately only uses one channel and thus Scan is set to Disabled. It also only gets the conversion once. I want to know how to use that mode to read multiple channels.

Kind Regards

Antonie

T J
Lead
Posted on April 11, 2017 at 16:02

my ADC_init has these different lines...

  hadc.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;

    /**Configure for the selected ADC regular channel to be converted.

    */

  sConfig.Channel = ADC_CHANNEL_1;

  sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;  // = (0x00001000U) 

  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_5;

  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)

  {

    Error_Handler();

  }
abotha
Associate III
Posted on April 12, 2017 at 11:14

Thank you

Marsh.Nick

‌, changing from

'ADC_OVR_DATA_PRESERVED'to '

ADC_OVR_DATA_OVERWRITTEN' fixed my problem!

noval
Associate II
Posted on May 23, 2017 at 11:50

hi, why i get this error and warning?

error: use of undeclared identifier 'LL_ADC_RESOLUTION_12B'

warning: implicit declaration of function '__LL_ADC_CALC_TEMPERATURE'is invalid in C99
Frank Sanders
Associate
Posted on August 25, 2017 at 11:41

Hi , your code is correct and must, Ranks 2,3, and 4 seems Rank 1, you should be use of Array for get a ADC Result same Below :

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