3

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

Guillaume Petitjean
  • 2,408
  • 1
  • 21
  • 47

1 Answers1

2

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.

  • 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