cancel
Showing results for 
Search instead for 
Did you mean: 

TIMx Link TIMX to Measure External Frequency

ESega.1
Associate II

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

9 REPLIES 9

Is there a question?

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

JW

TDK
Guru

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

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!

> 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
Associate II

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

0693W00000BclPrQAJ.jpg 

I don't use CubeMX, sorry.

JW

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();

 }

> 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