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.