cancel
Showing results for 
Search instead for 
Did you mean: 

Using ADC in interrupt mode, using callback HAL_ADC_ConvCpltCallback() to read values from two channels. But I am getting OVR error.

joemccarr
Senior

I place a break point in the callback HAL_ADC_ConvCpltCallback() and the first time it is entered EOC, EOS, OVR are all set. So I have already missed reading a conversion. How are mulitple values read using interrupts. After reading through the docs the call back should be entered at any eoc, eos or ovr. So I would expect the callback to be called twice each time I start a conversion using  HAL_ADC_Start_IT(&hadc) since i am scanning two channels.

Thanks for any light you can shed on this.

8 REPLIES 8

You did not care to tell us which STM32 model you are using.

The first conversion sets EOC and processor starts to enter the ISR, where it stops due to the breakpoint. But ADC already started the second of the two conversions and by the time the debugging pod succeeds to read out the ADC registers, it already finished its conversion, setting EOS and - as the data register had not been read out in time - also the overflow.

Interrupt generally may be too slow for sequences of ADC conversions, use DMA.

JW

joemccarr
Senior

I am using STM32f030R8 nucleo board. Pardon for the omitted information.

As you say the break point stopped the program but the adc had already started on the next conversion.

Everything worked when I increased sample time greater than 41 cycles.

As you said DMA is the better way.

Thank you for responding. Have a great day.

VRapa
Associate II

I am facing the same issue joemccarr.

In my case I want to scan 3 channels in STM32H7 ADC1.

I used  HAL_ADC_Start_IT(&hadc1); to start the ADC1 as interrupt mode

void HAL_ADC_ConvtCpltCallback (ADC_HandleTypeDef *hadc)

{

value = HAL_ADC_GetValue (&hadc1);

}

Here how can I read multi channel readings in ex: value[3] buffer

I blocked here from more than a week. Can anyone please help me on this?

Thanks in advance

uint16_t value[3];
uint8_t adcIdx;
 
void HAL_ADC_ConvtCpltCallback (ADC_HandleTypeDef *hadc) {
  value[adcIdx] = HAL_ADC_GetValue (&hadc1); 
  adcIdx = (adcIdx + 1) % 3;
}

but as I've said above, better use DMA.

JW

joemccarr
Senior

Jan answer works. Also he is correct about using dma. The ADC is fast so getting multiple channels is better done with DMA. I reserved a 1000 memory locations and also used a counter in the interrupt routine. When the count reached 1000 I hit a breakpoint then looked in memory to verify there are no missing values. My values were set to be stable and different so I knew if any were missed. Also in my interrupt routine I restart the sequence of reading the channels a

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* cat){
 
	 if((ADC1->ISR & ADC_ISR_OVR)== 1)
	    sendstring("OVR ERR");
 
	*(storage+count)= HAL_ADC_GetValue(cat);
	count++;
 
	if (count == 1001){//when #conversion > 1000 reset count. This will cause overwrite of SRAM storage locations
		HAL_ADC_Stop_IT (&hadc);
		count=0;
	}
 
	if( count%2==0 )  //every two conversion restart ADC w/interrupts
		HAL_ADC_Start_IT(&hadc);   //start adc conversion and use interrupts when EOC occurs
 
}

Thank you so much Jan

Good information Joemccarr. Thank you so much

Geraldo Pereira
Associate II

Hi Joemccarr,

I need write a code like this to detect ADC overrun in a STMF429zi and STFF767zi kit. Could you give me a hint? I tried your code, but the boards are different. I´m just read the doc, but If you could give me a hint, I´ll be great.

Thanks,

Geraldo.