Timer, ADC and DMA autonomous data logging …. no CPU

This post pulls together the work from prior posts on the timers, ADC, DMA and GPIU for the STM32F372.

The idea is to get the MCU to do periodic ADC measurements and store the results away on its own without needing the CPU to intervene. This means no interrupts or polling, just the peripheral blocks working together on their own. This type of design is becoming more and more common in the low power world where the CPU and its subsystem is kept asleep, leaving the peripherals to do their job with the CPU only woken when some control needs doing.

The demo works like this:

ADC_DMA demo

Timer 2 is set up to produce a PWM train with a 5 second period. I use 2 channels in the same counter with the same mark:space ratio settings so that the first can drive the ADC whilst the second flashes an LED so that I know something is happening…

Timer2 has a nice feature where you can set it to send a Trigger Event at each Update Event (UEV). Here I set the UEV to be when the counter spills over the period count and gets re-zero’d. This Trigger Event can kick the ADC into action causing it to do a measurement. But here’s the gotcha: not every channel of every timer can do this. On the F372, only the following:

  • Timer 19: channels 3 & 4
  • Timer 2: channel 2
  • Timer 4: channel 4

So pick your timer carefully…

When the ADC is kicked into action, is takes a measurement and then itself can signal the DMA engine to start. The result needs storing away in memory since the ADC will over-write the last data after the next measurement.

Here is the code:

Note again I am not using the ST driver code. When you move beyond their Discovery boards, I find their code difficult to port to custom systems without bringing along the entire code base. It serves its purpose as a demo well, but not much beyond that.

It was interesting to tie the ADC input to the battery Vdd, make a couple of hundred measurements and then look at the noise on the data:

ADC 200 points

With full scale 3300mV as code 4032, 3 standard deviations on 200 data points came in at 1.36 codes or 1.1 mV. I’d like to build a power supply accurate to 10mV; should be possible with some careful low noise board design.




Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">