cancel
Showing results for 
Search instead for 
Did you mean: 

Use timers to measure external clock frequency

JScot.2
Associate II

I have two external clocks connected to TIM1 and TIM2 of the stm32f746 (disco). I'm basically trying to implement a frequency counter of the clock connected to TIM2. The TIM1 clock will act as window (driven by a TCXO). In my test setup the TIM2 clock is 2500kHz and the TIM1 clock is 78.125KHz (=TIM2 clock/32). So I know what I should expect.

My idea is to create window with the TIM1 using counterPeriod=625. I also check TIM1 with "one pulse mode". I.e. provided that TIM1 will act as a window, I should expect to count 625x32=20000 cycles of the TIM2 clock.

I have attempted to create a master (TIM1)/ slave (TIM2) and enable counting by setting TRGO (cnt_en).

I have also attempted to use compare pulse (OC1) and use "output compare no output" and read compare register. This was described here (however using system clock as window)

Whatever I try the TIM2 clock either does not count at all or count continuously, I'm nowhere near to get '20000'.

I'm mainly reading this document but find it hard to understand..

Any suggestions are most welcome.

2 REPLIES 2

Start with forgetting about CubeMX/Cube/HAL.

Read the timer chapter in RM (for TIM2; you don't need to use the "advanced" (mostly complementary-output-related) functions of TIM1 so that reading is sufficient for TIM1 too). It's not an entertaining reading, but do it, perhaps several times. It's better to experiment during reading.

What you probably want to use in TIM1 is OPM as you've said (see description of TIMx_CR1 register), and one of its channels to Output Compare, PWM mode 2 (see TIMx_CCMRy and TIMx_CCER for the enable bit, CCEx). Yes, you don't need to output it into a pin, but it might be better, so that you'll see how is it working, on oscilloscope/LA. What you need though is to set the given channel's OCxREF as TRGO in TIM1_CR2. Finally, set the given channel's TIM1_CCRx to 1 and TIM1_ARR to one higher than your desired window.

What you probably want to use in TIM2 is the Gated mode at the slave. Read the TIMx_SMCR register fields descriptions.

Then start TIM1 by setting TIM1_CR1.CEN.

After each TIM1 cycle (i.e. when TIM1 Update event kicks in, checked either in loop in main() or in respective TIM1 interrupt) read out TIM2_CNT, that's your reading; then reset TIM2_CNT and enable TIM1_CR1.CEN again.

That's all.

> I'm mainly reading this document but find it hard to understand..

That's because you haven't read the TIM chapter in RM, and haven't performed a few dozens of simple experiments, yet.

JW

JScot.2
Associate II

Thanks for your tips! Did not know about the reference manual ( just started with stm32) and Google only provided me with the timer cookbook (which seems to assume knowing everything already). I feel better now 🙂