cancel
Showing results for 
Search instead for 
Did you mean: 

ADC in continuous mode with DMA stops instead of running indefinitely

Robert_149494
Associate II

We have a STM32U575xx chip, where I want to read a bunch of voltages continuously.

These voltages don't need to be measured at a particularly high rate, nor does the timing need to be strict. So it seemed efficient to run the ADC continuously with DMA. We expect that somewhere in memory there are constantly updating ADC readouts, and we can read these values when we want to, without any blocking calls. Any unused values can just be overwritten again.

However, this doesn't work entirely: we can do a non-blocking ADC read with DMA, but it seems to be only a single read, while I was expected a continuous readout because the ADC is in independent mode.

We start the ADC/DMA on init:

 

        HAL_ADCEx_Calibration_Start(&hadc1, ADC_CALIB_OFFSET_LINEARITY, ADC_SINGLE_ENDED);
        HAL_ADC_Start_DMA(&hadc1, m_adc1Values, Adc1NbrChannels);

 

Why does this ADC stop? Am I missing a setting, or does 'continuous' and 'independent' not mean what I expect it to?

 

It concerns ADC1, channels 1 to 7. We set it up with GPDMA1, channel 0. The complete CubeMX configuration is below.

 

Our workaround now is to just restart it whenever the DMA has stopped, with this entry in our on-tick callback:

 

        if (HAL_IS_BIT_CLR(hadc1.Instance->ISR, ADC_FLAG_EOC))
        {
            HAL_ADC_Start_DMA(&hadc1, m_adc1Values, Adc1NbrChannels);
        }

 

 

 

5 REPLIES 5
Karl Yamashita
Lead III

Your screen shots are unreadable. 

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.
gbm
Lead III

In the code above, you don't start the ADC. You've only started the calibration process which is a one time thing. Wait until the calibration is done then setup the DMA and start the ADC.

It will probably be useful to use continuous ADC conversion with DMA in circular mode. STM32 doesn't like it's ADC to be stopped for more than 0.5..1 ms.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice

Really? The pictures are in high resolution and I can read them fine. You'd have to open the file in the browser and click the zoom button or download the bitmaps first and use a local viewer. Direct links:

https://community.st.com/t5/stm32-mcus-products/adc-in-continuous-mode-with-dma-stops-instead-of-running/m-p/760651?attachment-id=29553

https://community.st.com/t5/stm32-mcus-products/adc-in-continuous-mode-with-dma-stops-instead-of-running/m-p/760651?attachment-id=29554


@gbm wrote:

In the code above, you don't start the ADC. You've only started the calibration process which is a one time thing. Wait until the calibration is done then setup the DMA and start the ADC.


HAL_ADC_Start_DMA() starts the ADC + DMA, doesn't it? I know for sure we do start it successfully, because we get proper readouts. And with that restarting loop above we get continuously updated values, it's just that I wanted to avoid this loop.

 


@gbm wrote:

It will probably be useful to use continuous ADC conversion with DMA in circular mode. STM32 doesn't like it's ADC to be stopped for more than 0.5..1 ms.


DMA is already in circular mode, visible in the screenshot.

Just have a look inside of this function. Also you can look for similar named HAL calls, that would give you the clue, if you are calling the right one.