2017-10-30 05:15 AM
I am working with STM32F765BIT MCU in our custom board, In that I need to measure some external signal frequency.
I am using timer in input capture mode to measure the frequency. I have taken some reference example and made same changes in my code. With that i am able to get capture complete call back interrupt ,but getting zero frequency.
I am running MCU at 216MHz clock and using channel1 of Timer5 as input capture mode.
I am not able to get what could be the problem, Can anyone please help me in resolving this issue.
/**************************************************Init ************************************************************/
static void MX_TIM5_Init(void)
{TIM_MasterConfigTypeDef sMasterConfig;
TIM_IC_InitTypeDef sConfigIC;htim5.Instance = TIM5;
htim5.Init.Prescaler = 0; htim5.Init.CounterMode = TIM_COUNTERMODE_UP; htim5.Init.Period = 0; htim5.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim5.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_IC_Init(&htim5) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); }sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim5, &sMasterConfig) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); }sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI; sConfigIC.ICPrescaler = TIM_ICPSC_DIV1; sConfigIC.ICFilter = 15; if (HAL_TIM_IC_ConfigChannel(&htim5, &sConfigIC, TIM_CHANNEL_1) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); }}
/**********************************************call back function****************************************************************/
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{ if(htim != &htim5 ) return; if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) { if(uhCaptureIndex == 0) { /* Get the 1st Input Capture value */ uwIC2Value1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); uhCaptureIndex = 1; } else if(uhCaptureIndex == 1) { /* Get the 2nd Input Capture value */ uwIC2Value2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);/* Capture computation */
if (uwIC2Value2 > uwIC2Value1) { uwDiffCapture = (uwIC2Value2 - uwIC2Value1); } else if (uwIC2Value2 < uwIC2Value1) { /* 0xFFFF is max TIM3_CCRx value */ uwDiffCapture = ((0xFFFF - uwIC2Value1) + uwIC2Value2) + 1; } else { /* If capture values are equal, we have reached the limit of frequency measures */ Error_Handler(); } /* Frequency computation: for this example TIMx (TIM3) is clocked by 2xAPB1Clk */ uwFrequency = (2*HAL_RCC_GetPCLK1Freq()) / uwDiffCapture; printf('Frequency = %d\r\n',uwFrequency);uhCaptureIndex = 0;
} }}/**************************************************************************************************************/
The control is coming to this call back function but I am getting uwDiffCaputre as zero.
Thank you.,
#timer #stm32f72017-10-30 05:29 AM
Hello,
See your TIM5 configuration structure.
htim5.Init.Period = 0;
You should set a larger Period (depending of your maximum period of input signal)
On your F765 device TIM5 is clocked by APB1 at 54MHz.
As you don't set a prescaler, your timer count at 1/54MHz.
Can you try with
htim5.Init.Period = 0xFFFF and manage a second callback to manage Period Timeout.
Regards
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2017-10-30 05:32 AM
What is the incoming frequency range vs the timer clock frequency?
2017-10-30 11:15 AM
Thank you for the reply.
I have made suggested changes and now its absolutely working fine , I am able capture frequency of input signal. But it works only in the range of 3Khz to 999Khz. What I suppose to do if I want to measure very lower frequency in the range of 50Hz ,100hz and so on.
Thank you.,
2017-10-30 11:31 AM
Isn't TIM5 a 32-bit timer? Use the range properly, ie Period = 0xFFFFFFFF
Also this code is overly complicated, unsigned math of appropriately size variables will wrap automatically
if (uwIC2Value2 > uwIC2Value1)
{
uwDiffCapture = (uwIC2Value2 - uwIC2Value1);
}
else if (uwIC2Value2 < uwIC2Value1)
{
/* 0xFFFF is max TIM3_CCRx value */
uwDiffCapture = ((0xFFFF - uwIC2Value1) + uwIC2Value2) + 1;
}
This will work for ALL values, assuming you use uint16_t or uint32_t depending on the TIM range
uwDiffCapture = (uwIC2Value2 - uwIC2Value1);
2017-10-30 11:35 AM
Yes, 32-bit, so read the manual, should have range to measure fractional Hz
2017-10-30 12:28 PM
Clive One is right TIM5 is 32bit. And you need to cast
uwIC2Valuex variable to uint32_t for computation.
To achieve low frequency measurement, you can apply a prescaler to TIMER 5 internal clock
such as
htim5.Init.Prescaler = 54 - 1; /* - 1 because Timer count from 0 to 0xFFFF FFFF */
Which give you a new TIMER resolution of APB1 = 54MHz / (54) = 1MHz ie to 1µs resolution.
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2017-10-30 02:25 PM
Even at 54 MHz a 32-bit timer can measure over a minute between pulses, I'd take the additional precision.
Would cast the delta computation to a double before doing the math on frequency.
2017-10-30 10:13 PM
Take the lowest frequency to measure, make the timer overflow longer than that.
Then for as many MSB unused timer bits, crank up the timer frequency more more LSB of precision (optional)
When the frequency is too high, we usually prescale it before measurement (to measure multiple periods).
This way, the timer other channels are still useable.
Otherwise, you can also use the incoming signal as the timer's clock and measure the pulses over 1 second... or more, as Clive said.
Multiple options, best fit depends on knowing what's the application needs and constrains.
2017-10-31 12:10 AM
Hi Clive One.,
Yes TIM5 is 32bit and I have changed Period = 0xFFFFFFFF , now I can able to measure frequency of 1Hz , 10Hz and so on . but when I tried to measure 500KHz its not working. Is there any Max frequency limit for this MCU, if so it relate to which parameter. If I suppose to measure all frequency in range of 1Hz to 1MHz what procedure should I follow.
Can please elaborate the usage timer in input capture mode, and how it works internally .
Thank you.,