cancel
Showing results for 
Search instead for 
Did you mean: 

How to setup ADC DMA to synch with timer? STM32F4

joshuahjamesmccrory
Associate II
Posted on March 10, 2017 at 22:43

I'm trying to setup 3 ADCs to read on a timer tick. On the STM32cube the timer can be set to 'Output Compare' to a single channel. And the ADC's can be set to external trigger conversion on a 'Timer Capture Compare # Event' Finally in the specific settings after a timer has been enabled, the timer can have a trigger event selection. If i'm trying to synch 3 ADCs to all write to separate buffers, what settings do i need to achieve that ?  

13 REPLIES 13
joshuahjamesmccrory
Associate II
Posted on March 11, 2017 at 17:18

Ok, So after digging a little more, i now know why i can't do what i was trying to do. Each DMA at a specific time step is only going to stransfer one piece of info from one point to another. My original intent was to have 3 ADCs simultaneously measuring values, drawing said values to separate buffers over DMA. On the STM32F407VG i'm using dedicates DMA2 to all ADCs, therefore i cannot physically write ADC values at the same exact time step to separate buffers since they all have to go across DMA2. So if i wanted to do 3 independant ADCs over DMA, they will be spaced apart by some sort of lag regardless since they all have to use the same DMA. Next i thought, well i could use Triple mode and at least have them organized and minimal time difference between each sample. With that i wanted to then use MEMTOMEM to separate the values from the one buffer that triple mode writes to into separate buffers, BUT MEMTOMEM also requires using DMA2, thus i cannot do that. Therefore i can only draw values over triple mode, then postprocess the data to separate the ADC outputs. Or use DMA MEMTOMEM after i'm done reading ADCs. If you use an MCU that has MEMTOMEM on separate DMAs OR the ADCs are on separate DMAs, then you can pull this off.

Finally, to my original question. the most basic settings to get an ADC to sync with a timer, you can select a timer with a 'trigger out' event in the ADC settings: (C

onfiguration | ADC | ADC_Regular_Conversion_Mode | External Trigger Conversion Source)

 Then under the timer settings: (C

onfiguration | TIM# | Trigger Event Selection) You can select 'Update Event'. Not all timers have a 'Trigger Out' event, and i think the method above using Capture Compare Events works as well, as long as you select the correct trigger event selection in the timer settings (i don't know which setting is needed for a capture compare event yet) And the Timer settings under 'Pinout' are set to 'Output Compare, No Output' on a channel and then the channel is the 2nd Number on the '

External Trigger Conversion Source' Capture Compare Event in the ADC settings.

So my solution to 3 ADCs simultaneously is to use the triple mode (Make sure you use  'HAL_ADC_Start' for ADC2 and ADC3 1st, then '

HAL_ADCEx_MultiModeStart_DMA

' for ADC1) to write data to a single buffer, use the MCU to write the values to a separate FLASH buffer, and either have buffer large enough to encompass all the data i want to capture, or have the write to flash rate be as minimal as i can to effectively capture the data i need.

Please anyone feel free to correct anything i wrote on the wall of text above, thanks!

Posted on March 11, 2017 at 22:39

You can make all 3 channels fetch an analog input simultaneously by triggering all 3 from the same output compare channel.

if the DMAs grab those values with slightly different timing, that does not affect the instantaneous capture that you have saved in the 3 DR registers.

that way you can still have 3 separate DMA channels automatically shifting data to separate channel data buffers

Rich G
Associate II
Posted on February 05, 2018 at 19:22

Hi, did you ever get this working?  I'm wanting to capture 3 analogue sources at a regular interval without loading the CPU.  i.e. using a timer to trigger ADC in scan mode and use DMA.  I just can't seem to get it working.  I cannot get the ADC capture complete callback to be invoked. I'm wanting to use CubeMX as much as possible; I'm new to this!

Thank you! 

184254CGIL2