I have difficulties understanding how STM32 ADC works. I want to do something simple ie. sample and convert regularly ( @ 250Hz ) on 2 GPIOs. For now I did it in a "dummy" way: setup ADC in basic single mode, then launch a timer @250Hz and at each timer interrupt start the ADC to convert only one sample on each channel. But I don't think it is the right way to do and I'm worried about the lack of precision in terms of timing between samples. Could you explain how I should configure the ADC to sample/convert continuously at a given frequency during a given number of samples ? I didn't find much usefull resources on the net and the reference manual is pretty complex. Thank you
1 Answers
Regular or Injected conversion sequences
Each ADC can process two lists of channels to convert, a regular sequence with 16 channels (SQR1
-SQR4
), and an injected sequence with 4 channels (JSQR
).
One of the main differences is that the regular conversion stores all results in a single shared data register (DR
), which must be read out and stored before the next conversion step finishes. When there are more than one channels in a regular sequence, it's best to use DMA to store the conversion results. As you want something simple, I won't go into DMA now.
The injected conversion sequence stores each result in its own register (JDR1
-JDR4
or JDR[4]
), then the software can read the results once the sequence finishes, which can be detected by polling the JEOS
bit in the ISR
register, or by enabling the interrupt with the JEOSIE
bit in IER
.
It is possible to start the injected sequence automatically when the regular sequence is finished (JAUTO
bit in CFGR
), that way it's possible to start 5 conversions in a row on each ADC unit, and have the results in different registers at the end.
Starting conversion at regular intervals
Instead of starting a conversion each time by software, you can set up a timer to start an ADC conversion sequence directly.
First, see the chapter titled Conversion on external trigger and trigger polarity (EXTSEL, EXTEN, JEXTSEL, JEXTEN) in the reference manual. There are lists of possible trigger events for regular and injected sequences. Pick a TRGO event from the table, set EXTSEL
and EXTEN
, or JEXTSEL
and JEXTEN
accordingly.
You might want to enable an end of sequence interrupt (EOSIE
or JEOSIE
in IER
) now to notify the software when the sequence finishes.
Arm the ADC by setting ADEN
and ADSTART
or JADSTART
in CR1
, the conversion will start once the trigger from the timer arrives.
Program the timer that you selected from the table above for the desired frequency, and set the MMS
bits in CR2
to 010
(Update). Each overflow (update) of the timer will generate a trigger event, starting the next ADC conversion sequence. It's not necessary to enable the timer interrupt.
Using more ADC units
If there are more than one ADC units in your controller, you can start them simultaneously using the same trigger on each one. This way you can do 2 or 3 conversions at the exact same time, or start up to 15 conversions and have the results at once without using DMA.

- 7,779
- 1
- 23
- 39
-
I've implemented what you suggested (thank you very much for your time BTW) and it works fine except for one thing. I have setup TIM15 as trigger for ADC. I had already tested the setup of this timer and it is counting at the right frequency : when I launch the timer alone, I get timer UIF interupt at the right frequency, as expected. I am able to trigger the ADC sampling sequence but the sampling rate (ie. the rate at which I get ADC IRQ) is twice slower than the timer update frequency ( I have only one channel). – Guillaume Petitjean Apr 26 '18 at 12:50
-
In other words I get an ADC EOS interrupt only one out of 2 timer updates. The timer update occurs every 5seconds so it's not a problem of ADC sampling being longer than timer update. – Guillaume Petitjean Apr 26 '18 at 12:50
-
Will ask a separate question on this issue. – Guillaume Petitjean Apr 26 '18 at 14:34
-
@GuillaumePetitjean Do it. Post the code, otherwise it'd be hard to guess what went wrong. – followed Monica to Codidact Apr 27 '18 at 06:54