2
votes

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

1 Answers

2
votes

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.