cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L051 ADC Overrun (single conv., no DMA)

dtpnilsson
Associate II

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.

1 ACCEPTED SOLUTION

Accepted Solutions
mckenney
Senior

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

View solution in original post

2 REPLIES 2
mckenney
Senior

> 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

Thank you, that was the issue!