0
votes

My processor is an STM32F437ZGT6 and I wish to count two different pulse trains (RPM). The range is quite wide, I may have an engine that idles at 150 rpm and we get a pulse from the cam, so 0.5 pulses per revolution, or 1.25 pulses per second. At the other extreme I may need to count 460 flywheel teeth at 3000 rpm, 23000 pulses per second. I have a prescaler available so I can divide the external event by up to 8 but even so this become too intense at higher speeds because every event or eight event causes an interrupt.

One alternative I am considering would be to have one timer use the external event as the clock and it would just count events within a time window. My difficulty comes from determining how to use another timer to control the window by setting and clearing CEN or some similar action.

In RM0090, section 18.3.15 Timer synchronization the example shows one timer controlling another, timer 1 controlling timer two. I thought that may be useable but althought I did not read otherwise I don't see that any two timers could be paired. The signal I am interested in actually feeds two timers. TIM1 ch1 and TIM9 ch1.

Any suggestions would be appreciated as I don't want to cobble up some Rube Goldberg scheme where one timer fires off an ISR and then the ISR opens and closes the time window.

I should have noted that a lookup table is provided that provides the expected engine speed and the number of pulses per revolution.

Thanks, jh

3

3 Answers

0
votes

If you want to just count external events, you can select external clock source for timer. (Point "Clock selection" of reference manual). SPL should have an example. And read count from Tim CNT register every time you need. The problem here is to read counts often enough.

Usually auto-reload register is 2 bytes so you have up to 2 ^ 16 counts before overflow, and loosing counted value. Timers 2 and 5 have 4 bytes auto-reload registers so you have up to 2 ^ 32 counts.

If you need more then 2 ^ 32 counts you have at least two ways:

  - Timer cascade, by setting one timer event as a clock for another. You can find this in the reference manual as "Using one timer as prescaler for another timer". Cascading offers you up to 2 ^ 64 timer. There is an example for SPL in "TIM_CascadeSynchro" folder.   - Less beautiful, but more easy way is to create a counter variable and, increment it in timer irq handler. Number of counts may be found as cnt_variable * TIMx-> ARR. Several cascaded variables give the unlimited counter).

0
votes

Thanks for the post. I will try to add a little detail. RPM 1 is fed into TIM3 ch2 and TIM4 ch1. RPM 2 is fed into TIM1 ch1 and Tim9 ch1. Both have a range of 1.25 pulses per second up to 30000 pulses per second. I am given the number of pulses per revolution which can range from 0.5 to 460 and the expected engine rpm, 150 - 3000 rpm so I can scale things a bit. The reason for feeding two different timers is to be able to use different counting techniques based on speed (pulses per second). For low speed I can capture events (pulses) and grab the timer count using an ISR. But when the pulse count gets high I want to use a different method so as not to incur more than 1000 interrupts per second per channel. So my idea there is to have one timer control another. One timer would simply count events without generating interrupts. The second counter would control the period of time that the first timer would be allowed to collect events.

Thanks, jh

0
votes

Seems like you need: timer synchronization with enabling/disabling slave timer according to the trigger output of master timer. Description can be found in the following sections of RM0090:

  • 18.3.14 Timers and external trigger synchronization in paragraph Slave mode: Gated mode
  • 18.3.15 Timer synchronization in paragraph Using one timer to enable another timer

Also good explanation can be found in TIMx register section for registers TIMx_SMCR: bits TS and SMS; TIMx_CR2: bits MMS.

TIMx internal trigger connection (tables 93, 97 and 100) сontains possible connections of the trigger output of one timer with the input of another. Timers that you can use as master are marked in the picture below: enter image description here

TIM_ExtTriggerSynchro example from SPL library can be used for code copy-paste.

I think the best way is:

  1. Set RPM pins as external clock source for slave timer.
  2. Set enabling/disabling of slave timer from the output compare of master timer. So changing TIMx_CCRx register value you can change duration of measurement.
  3. Set master timer interrupts on update event (maybe on few events TIMx_RCR register).
  4. Do all the calculations in master timer interrupt handler

Also it seems to me that you can just use 16 bit timer as RPM counter. Even on 30000 pulses you will have overflow every 2^16/30000 = 2,18 seconds which is rarely rare for STM32F4 clock frequencies. And use other timer, with, for example, 2 second period, interrupt for calculations.

Good luck!