Skip to main content
dtpnilsson
Associate II
July 13, 2020
Solved

STM32L051 ADC Overrun (single conv., no DMA)

  • July 13, 2020
  • 2 replies
  • 864 views

I keep getting OVR (overrun) interrupts when running below simple code.

OVR interrupt happens every 10~20th iteration of the loop. Overrun should not occur because the data register (DR) is read after measurement is completed.

Why do I get an overrun and how do I prevent it?

uint32_t highest_meas = 0, temp_meas = 0;
 
for(uint16_t i=0; i<176; i++)
{
	// Make measurement
	ADC1->CR |= 0x4; // Start measurement
	while(ADC1->ISR & 0x4 == 0){} // Do nothing until EOC=1
		
	temp_meas = ADC1->DR; // Get measurement
 
	if(temp_meas > highest_meas)
	{
		highest_meas = temp_meas;
	}
}

This is the configuration of the ADC:

 hadc.Instance = ADC1;
 hadc.Init.OversamplingMode = DISABLE;
 hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV1;
 hadc.Init.Resolution = ADC_RESOLUTION_12B;
 hadc.Init.SamplingTime = ADC_SAMPLETIME_3CYCLES_5;
 hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
 hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
 hadc.Init.ContinuousConvMode = DISABLE;
 hadc.Init.DiscontinuousConvMode = DISABLE;
 hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
 hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
 hadc.Init.DMAContinuousRequests = DISABLE;
 hadc.Init.EOCSelection = ADC_EOC_SEQ_CONV;
 hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
 hadc.Init.LowPowerAutoWait = DISABLE;
 hadc.Init.LowPowerFrequencyMode = ENABLE;
 hadc.Init.LowPowerAutoPowerOff = DISABLE;

ADC uses PCLK (as the rest of the system) which is MSI clock 262.144 kHz.

This topic has been closed for replies.
Best answer by mckenney

> while(ADC1->ISR & 0x4 == 0){} // Do nothing until EOC=1

This condition is always false. Try:

> while((ADC1->ISR & 0x4) == 0){} // Do nothing until EOC=1

I didn't check whether the 0x4 is correct. I'm pretty sure there's a name defined for it, though.

2 replies

mckenney
mckenneyBest answer
Associate
July 13, 2020

> while(ADC1->ISR & 0x4 == 0){} // Do nothing until EOC=1

This condition is always false. Try:

> while((ADC1->ISR & 0x4) == 0){} // Do nothing until EOC=1

I didn't check whether the 0x4 is correct. I'm pretty sure there's a name defined for it, though.

dtpnilsson
Associate II
July 13, 2020

Thank you, that was the issue!