cancel
Showing results for 
Search instead for 
Did you mean: 

Quick way to read multichannel, single conversion ADC without DMA on STM32F301.

DRH
Associate III

Hi,

I have to read a sequence of five ADC channels each 100us. In the past, I used the common way by DMA channel 1 and an interrupt at reading completion to get all values.

Unfortunately I need most of the DMA for other purpose this time and I'm wondering what's the most efficient way to get several ADC results without it. Is polling the only solution? I haven't tested polling, but it seems to be too slow.

I guess there is no way to use another free DMA? The only available DMA channels are 4 and 6.

Thank you for any idea and support.

8 REPLIES 8
DRH
Associate III

Timer 1 and Timer 2 are used, timer 2 triggers the ADC measurements. I'm wondering if there is an option to sync Tim2 and Tim16 so I can use Tim16CC to make DMA channel 1 (Tim2CC) available, but it seems that there is no way to synchronize both timers?

DRH
Associate III

I don't like it but another idea may be to configurating all ADC channels with the same config and speed, calculating the time from conversion start to end and using another timer (e.g. Tim16) with an available DMA channel to transfer the ADC results to an array. I`m afraid that without the coupled hardware feature, this will generate a lot of trouble, especially in combination with other DMA channels. On the other hand, I can trigger the timer and the adc together and if the results stay available till the adc update, it may be possible also with slightly drifts.

What are your thoughts? I'm happy for any supporting idea.

TDK
Guru

If you don't want polling and you don't want DMA, what other option is there? I don't see how you're going to use a timer to transfer ADC results, unless you're going to do it within the timer update IRQ, but that's not a DMA solution.

If you feel a post has answered your question, please click "Accept as Solution".
DRH
Associate III

Thank you very much for your response. The point is, that the ADC exclusively works with DMA channel 1 and this channel is necessary for another functionality. Polling may be an option but I'm not sure if this will work well with a period of 100us (5 ADC conversions). DMA channel 4 and 6 are available but there is no hardware connection. The only option I'm currently thinking about is Timer 16 but I have to make some further tests.

Using IRQ means that each channel generated an interrupt? With other words, a period of 100us and 5 analog channels make it necessary to handle each interrupt and measurement within 20us (best case). This seems to be possible but didn't sound like the best approach.

My feeling said me, that it's a common issue that DMA channel 1 is necessary for other functions and that there are other great ideas out there that may help me finding a solution to get multiple ADC measurements within a short time and not too much IRQ cycles.

Do you see other options? DMA is fine (and preferred) but the only available channels are 4 and 6.

At 20us per sample, maybe an irq would work if you optimized it. I believe the irq can be set to trigger on every conversion rather than the end of all 5. Unlikely to work with HAL overhead. I dont see any other options. Seems like disabling interrupts and polling for 100us is a simpler solution. I doubt this scheme could tolerate another irq firing during the 100us.
If you feel a post has answered your question, please click "Accept as Solution".
Nikita91
Lead II

On an ADC there is 4 data registers for injected channels, and only 1 data register for regular channels.

You may use a sequence of 4 injected channels a and a regular conversion of 1 channel.

At the end of the conversion of the regular channel you can generate an interrupt then read the 5 registers.

DRH
Associate III

It seems to work. Further tests are necessary but it looks like the first results are fine.

I config ADC to measure a sequence but without DMA channel 1 support. Immediately after start of the ADC sequence (triggered by SW), I start timer 16 and use DMA channel 6 to transfer ADC results to an result array at timer update.

It's not really nice, because the wrong timer16 reload value will make the adc fail, but it seems to be the fastest solution.

Thank you very much. I read about ADC injected mode but didn't notice that the ADC provides four extra data registers. I will check that solution as well.

Unfortunately I have to increase the number of channels to seven, but if this will change again, your suggestion will provide the advantage, that it's completely provided by the ADC without using a DMA channel. The mentioned synchronization challenge will also be no issue.