Decoding PWM using cross-coupled timers on the STM32F372

The STM32F1xx has some neat features that allow you to cross-couple timers in interesting ways.

In the last post on timers, I synchronized 2 timers by using a master-slave configuration where the master resets the slave on every cycle. This time I use 2 cross-coupled channels of one timer in order to measure a PWM train frequency and mark:space ratio.

The trick to measure PWM is to use one counter to measure the period and the second to measure mark time, the latter reset by the first period counter on every cycle:

PWM

Here’s how it works:

  • The pulse train is applied to the pin of Timer 1 channel 1 (T1C1)
  • T1C1 edge detector outputs rising and falling edge signals as shown below.
  • The MUXs are cleverly designed so that you can use the edge signals from one channel to trigger the input of another channel. In this case, falling edge on channel 1 starts counter 2. This is set up in the CCER register.
  • The CCMR1 register is finally used to pick which channel’s edge causes the counter to start. In this case, we want the falling edge of timer1 C1 to start counter 2.
  • The rising edge of the next pulse causes the SMCR block to reset both counters. The value in Counter 1 will be the period and the value in counter 2 the mark. I use the SYSTICK timer to generate an interrupt every 2 seconds for reading the counter values.

TImer PWM

Here is code for the STM32F372 that implements PWM detection. The approach for STM32F100 is the same strategy, though there are differences in register lay out:

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="">