cancel
Showing results for 
Search instead for 
Did you mean: 

How to read ADC value using continuous Interrupt handler?

RShre.2
Associate III

I had tried Poll conversion and it worked fine, but I want to use Interrupt for ADC value reading, but for some reason, it is not working. Could anyone suggest me, where i went wrong?

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)

{

 adc_val = HAL_ADC_GetValue(&hadc1);

 /*If continuousconversion mode is DISABLED uncomment below*/

// HAL_ADC_Start_IT (&hadc1);

}

static void MX_ADC1_Init(void)

{

 /* USER CODE BEGIN ADC1_Init 0 */

 /* USER CODE END ADC1_Init 0 */

 ADC_ChannelConfTypeDef sConfig = {0};

 /* USER CODE BEGIN ADC1_Init 1 */

 /* USER CODE END ADC1_Init 1 */

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

 */

 hadc1.Instance = ADC1;

 hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;

 hadc1.Init.Resolution = ADC_RESOLUTION_12B;

 hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;

 hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;

 hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;

 hadc1.Init.LowPowerAutoWait = DISABLE;

 hadc1.Init.LowPowerAutoPowerOff = DISABLE;

 hadc1.Init.ContinuousConvMode = DISABLE;

 hadc1.Init.NbrOfConversion = 1;

 hadc1.Init.DiscontinuousConvMode = DISABLE;

 hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;

 hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;

 hadc1.Init.DMAContinuousRequests = DISABLE;

 hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;

 hadc1.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_1CYCLE_5;

 hadc1.Init.SamplingTimeCommon2 = ADC_SAMPLETIME_1CYCLE_5;

 hadc1.Init.OversamplingMode = DISABLE;

 hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;

 if (HAL_ADC_Init(&hadc1) != HAL_OK)

 {

  Error_Handler();

 }

 /** Configure Regular Channel

 */

 sConfig.Channel = ADC_CHANNEL_0;

 sConfig.Rank = ADC_REGULAR_RANK_1;

 sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;

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

 {

  Error_Handler();

 }

 /* USER CODE BEGIN ADC1_Init 2 */

 /* USER CODE END ADC1_Init 2 */

}

6 REPLIES 6
Bob S
Principal

> it is not working

Need more information. HOW is it "not working"? What steps have you tried to debug this?

A classic problem with using the interrupt callback functions is that the variable (adc_val in your case) is not declared "volatile". That causes the code in your main loop to be optimized to never actually read the variable, since from the compiler's standpoint it never gets updated.

MM..1
Chief III

If you need real autonomous ADC oflloaded from MCU = no instruction, you need add DMA.

And in your example code isnt START for ADC .

Not working, I meant, the value is always 0. I declared the adc_val as global variable. I haven't tried volatile. will have to see.

I haven't used DMA. I want to call interrupt handler. are these two the same? I have started the ADC in the HAL_ADC_ConvCpltCallback() function.

Your start is commented out and in normal situation you cant start first conversion in callback. First need start then get. In callback you need restart if continuos mode is off.

Oh that's because my continuous mode is enabled and I started the ADC in the main function.