cancel
Showing results for 
Search instead for 
Did you mean: 

Fastes way with as little blocking as possible to read ADC-values

Christian Wächter
Associate III

I'm currently thinking about how to make the ADC-readings not neccessary as fast as possible, but to cause as little blocking as possible. My current idea is to start the reading in the main() with

	// Start ADC with DMA support
	adc_dma_values_valid = 0;
	HAL_ADC_Start_DMA(&hadc, adc_values, 8);
 
	if (adc_dma_values_valid)
	{
		adc_dma_values_valid = 0;
		// do something with the adc_values
	}

The DMA Interrupt then will set the adc_dma_values_valid to 1

void DMA1_Channel1_IRQHandler(void)
{
	adc_dma_values_valid = 1;
	HAL_DMA_IRQHandler(&hdma_adc);
}

The other option would be to wait for the function to return a HAL_OK. But this will block the remaining program from running

while ( HAL_ADC_Start_DMA(adc_handler, adc_data, data_length) != HAL_OK );

2 REPLIES 2
John F.
Senior

One way is to use a timer to cause a periodic interrupt ("Update") then in the first timer interrupt service routine, start the ADC conversion and in the next, read the result. You can use a static variable in the ISR to keep track of which phase you're in ... whether to start a conversion or read a result. Obviously, you need to choose an interrupt rate that allows sufficient time for the ADC to convert.

Some STM32 ADCs support "Scan" mode which might also do what you want (used with a periodic trigger).

henry.dick
Senior II

"how to make the ADC-readings not neccessary as fast as possible"

that's easy to understand, 🙂

1) continuous adc + dma;

2) continuous adc + testing for completion;

3) single adc + interrupt;

4) single adc + test for completion;

...