cancel
Showing results for 
Search instead for 
Did you mean: 

Frequency capture in STM32F7

Edwin kaus
Associate II
Posted on October 30, 2017 at 13:15

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 #stm32f7
16 REPLIES 16
Posted on October 31, 2017 at 10:48

... or speed up your code, by setting higher optimization setting of compiler, and getting rid of superfluous code (aka Cube).

JW

Posted on October 31, 2017 at 10:39

Even an oscilloscope has knobs to change the time scale... use a prescaler for the incoming signal (usually CH1/2 or ETR when available). The incoming signal frequency will be divided by a power of 2.

AVI-crak
Senior
Posted on October 31, 2017 at 12:28

There are two methods for measuring frequency.

1) Measure the duration of the low and high state of the input, followed by the accumulation of the result and the calculation of the mean value. This method is suitable for changing low frequencies. The accumulated result is processed: first, the total average value is found, and then each report is multiplied by the logarithmic difference between the mean and the current value modulo. This cuts noisy distortions much higher or lower than the average level - peak values beyond the boundaries. This filtering is performed three to four times - until averaging is complete. In fact, the code works in real time, between capturing a new piece of data.

2) Measurement of the number of clock pulses per precise time interval. Filtering is possible, but its work will be visually noticeable. Because the length of time is chosen close to one second. This method allows you to measure high frequencies.

Both methods can be executed simultaneously, the processor resources are sufficient for such operations.

Variant when a phase detector is required to extract information from a frequency-modulated signal - other filters are used, but the general meaning remains the same.

Posted on October 31, 2017 at 13:41

Hai 

The same frequency capture I am trying with timer12 , but here i am not able to measure lower frequency like 10Hz,20Hz . what could be the problem . 

With Timer5 and same configuration I can able to measure those frequency(even 1Hz,2Hz and so on).

Isn't timer12 is 32 bit timer ,

Thank you.,

Posted on October 31, 2017 at 13:55

RTFM - TIM2 and TIM5 are 32-bit

See section 2.23.2 also Table 6

http://www.st.com/content/ccc/resource/technical/document/datasheet/group3/c5/37/9c/1d/a6/09/4e/1a/DM00273119/files/DM00273119.pdf/jcr:content/translations/en.DM00273119.pdf

 
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on November 02, 2017 at 10:54

If the diff is always zero but the ISR is being triggered then there must be a program flow bug. I didn't find a specific bug, but I would simplify the code. The ISR has a state, which is whether it is expecting the first or second edge (stored in uhCaptureIndex). The code would be simpler and hence easier to debug if the state were eliminated. This can be done by storing the previous capture time and always subtracting that from the TIM capture time (which is then stored as the previous time).

Posted on November 03, 2017 at 06:42

Hi

Turvey.Clive.002

I am very thankful for the support given by you.

I have another requirement with this timers . I need to count number of pulse for 1 second , presentlyI just kept one counter in input capture call back function. Is this only the effective method or else any inbuilt timer function available to do this .

I just want to count number of pulses for every second.

Thank you.,