Skip to main content
ESega.1
Associate II
July 4, 2021
Question

TIMx Link TIMX to Measure External Frequency

  • July 4, 2021
  • 6 replies
  • 4138 views

Am using NUCLEO-STM32H723 Nucleo-144 board.

Sorry, but I have no experience with the above MCU/TIMx.

My goal is to measure external frequency as accurately as possible.

I'm interested to know how to Link between two timers.

Example : TIM3 ( Master ) TIM2 ( Slave ).

TIM3 receive ETR2 (External clock) as clock source, and should Triger every 40 pulse to TIM2.

TIM2 should be Triger by TIM3 after 40 pulse ETR2 CLK , And capture Internal clock and calculating the frequency.

Do I need use TIM->CNT Or TIM2-CCR1 ?

Anyway this is the code I use.

main()

{

 HAL_TIM_Base_Start(&htim3);

 HAL_TIM_Base_Start_IT(&htim2);

 ....

 ....

 while()

 {

  

 }

  

  

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef* htim)

if(gu8_State == IDLE)

{

gu32_T1 = TIM2->CCR1;

gu16_TIM2_OVC = 0;

gu8_State = DONE;

}

else if(gu8_State == DONE)

{

gu32_T2 = TIM2->CCR1;

gu32_Ticks = (gu32_T2 + (gu16_TIM2_OVC * 65536)) - gu32_T1;

gu32_Freq = (uint32_t)(F_CLK/gu32_Ticks);

gu8_State = IDLE;

}

}  

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim)

{

  if(htim->Instance == TIM23)

  {

gu16_TIM2_OVC++;

}

}

0693W00000BclHJQAZ.jpg0693W00000BclG2QAJ.jpgI

This topic has been closed for replies.

6 replies

waclawek.jan
Super User
July 4, 2021

Is there a question?

If there is, start with reading out and observing/checking/posting both TIM's registers.

JW

TDK
Super User
July 4, 2021

> My goal is to measure external frequency as accurately as possible.

This can be done with a single timer in IC mode. Have the timer in freerunning (internal clock) mode and use internal capture to capture edges on the external signal. Use the difference between two successive values to calculate the frequency. For additional accuracy, take the average of this value over multiple readings.

"If you feel a post has answered your question, please click ""Accept as Solution""."
ESega.1
ESega.1Author
Associate II
July 4, 2021

Thanks you for quick reply!

This is what I do, but unfortunately the accuracy is not high.

Instead of catching every pulse and use (SW ) the difference between two successive values to calculate the frequency as you recommend.

I believe it is possible use HW TIMx`s to catch a fixed number of ascents by TIMx, and only then use TIMy calculate the frequency.

Please, Do you know how to use TIMx to waiting Triger from TIMy , and at the same TIMx also use internal capture?

Thanks in advance!

waclawek.jan
Super User
July 4, 2021

> Do you know how to use TIMx to waiting Triger from TIMy , and at the same TIMx also use internal capture?

In TIMx_SMCR, set TS to the proper TIMy, and leave SMS at 0 (internal clock); set the appropriate TIMx_CCMRx.CCxS to 0b11 i.e. Input Capture to come from TS.

JW

ESega.1
ESega.1Author
Associate II
July 5, 2021

Can you please confirm TIM2 (TIMx) setup according to your recommendation ?

 htim2.Instance = TIM2;

 htim2.Init.Prescaler = 0;

 htim2.Init.CounterMode = TIM_COUNTERMODE_UP;

 htim2.Init.Period = 4294967295;

 htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

 htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;

 if (HAL_TIM_Base_Init(&htim2) != HAL_OK)

 {

  Error_Handler();

 }

 sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; /* SMS at 0 (internal clock) */

 if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)

 {

  Error_Handler();

 }

 if (HAL_TIM_IC_Init(&htim2) != HAL_OK)

 {

  Error_Handler();

 }

 sSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET;

 sSlaveConfig.InputTrigger = TIM_TS_ITR2; /* TIMx_SMCR, set TS to the proper TIMy */

 if (HAL_TIM_SlaveConfigSynchro(&htim2, &sSlaveConfig) != HAL_OK)

 {

  Error_Handler();

 }

 sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;

 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;

 if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)

 {

  Error_Handler();

 }

 sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;

 sConfigIC.ICSelection = TIM_ICSELECTION_TRC; /* TIMx_CCMRx.CCxS to 0b11 */

 sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;

 sConfigIC.ICFilter = 0;

 if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)

 {

  Error_Handler();

 }

ESega.1
ESega.1Author
Associate II
July 4, 2021

"set the appropriate TIMx_CCMRx.CCxS to 0b11 i.e. Input Capture to come from TS."

Please, can you show me TIM2 Setup example ?

Attach my TIM2 Setup:

ESega.1
ESega.1Author
Associate II
July 4, 2021

0693W00000BclPrQAJ.jpg 

waclawek.jan
Super User
July 4, 2021

I don't use CubeMX, sorry.

JW

waclawek.jan
Super User
July 5, 2021

> Can you please confirm TIM2 (TIMx) setup according to your recommendation ?

As I've said, I don't use Cube.

The best way to check this is to run the code and then read out and check content of TIM registers.

JW