# Direct frequency measurement with two hw timers

In what modes would I set two timers to directly measure frequency on an STM32F303 microcontroller? Right now I set up one timer in ETR mode and gate it with systick software interrupts, but I would like to have a second timer gate it directly to increase the precision.

EDIT: Because of the low precision of the HSI - 0.1%, the clock needs to be switched to HSE.

I'm doing all of this in cubeMX so I won't be writing out the bits, you can find them in the reference manual -http://www.st.com/web/en/resource/technical/document/reference_manual/DM00043574.pdf

After some experimenting I figured it out. For simplicity, i'll write out the whole process of setting up 2 counters to measure frequency directly.

First the main counter, lets take TIM1:

• Set the clock to ETR2
• Set the trigger to ITRx, you can find the correct one by consulting the TIMx internal trigger connection e.g. if you want to TIM1 to be the main counter, you can gate it with TIM15 by selecting ITR0.
• Enable an input capture channel triggered by TRC, this will record the pulse count after each gate
• Now the classic timer stuff - Set the Counter Period (autoreload) to max 0xffff for TIM1

And thats the main counter set up. Now for the gating timer, lets take TIM15:

• Set the clock source to internal
• Set an output compare no output on channel 1 (any channel will do) Parameter settings:
• In the trigger output select Compare Pulse (OC1) as trigger event
• And set the appropriate prescaler, counter period and (pulse? not sure if its needed). E.g. for 1s, with 72MHz clock I chose 7199 for the prescaler and 9999 for the counter period
• The output compare mode should be in Frozen mode

Thats all the setup done. After generating the project, don't forget to start all timers, e.g.

HAL_TIM_Base_Start(&htim1);
HAL_TIM_IC_Start(&htim1, TIM_CHANNEL_1);
HAL_TIM_Base_Start(&htim15);
HAL_TIM_OC_Start(&htim15, TIM_CHANNEL_1);


And the frequency can be read out from the capture compare unit,

frequency= __HAL_TIM_GET_COMPARE(&htim1, TIM_CHANNEL_1);


This is of course assuming the gate time is 1s.

if i understand you right, you want to measure a external frequency connected to an i/o pin of your MCU?

And the second timer you need as a reference gate ? just to make sure i understand u right.

There are appNotes from ST about calibration of internal RC Osc. They describe how clocks and counters ("timer") are used to get best precision. I have a look if i find this again.

So in the end it depends on what freq. range you want to measure and which clocks you have available (freq und precision). can you tell me more about it.

my approach would be to conf. one timer unit into capture mode (capture from io pin)

• here is the document i announced: www2.st.com/content/ccc/resource/technical/document/… Apr 12, 2016 at 19:51
• Yes, I want to measure external frequency on an IO pin. The range should be from 10kHz up to the limit of the IOs. Therefore I want to use one timer to count the pulses and another timer to turn the first timer on and off in exact periods e.g. 100ms. Apr 13, 2016 at 10:06
• I just skimmed over the AN, it only describes how to calibrate the HSI clock, not how to measure on timers. Or am I missing something? Apr 13, 2016 at 10:10
• your are right, but in the end they also measure frequency. To its for inspiration. I implemented this calibration a year ago ... there was just one timer needed. i will have a look at the project and report here. can you tell me something about your available clocks ? (internal RC Osc or external crystal, which frequency). Apr 14, 2016 at 16:31
• This was meant as a proof of concept, therefore everything on the micro is available. And there is an ext 8MHz crystal. Apr 15, 2016 at 16:29