2017-11-09 11:25 PM
Hello,
I'm trying to measure the frequency of a PWM signal ( 600 Hz) with the Input Capture functionality with an STM32F103.
I do these steps:
This is the callback invoked when a rising edge is detected:
void HAL_TIM_IC_CaptureCallback( TIM_HandleTypeDef *htim )
{ uint16_t capturedValue; uint16_t delta; if( (htim == htim4) && (htim->Channel == TIM_CHANNEL_4 ) channelId = PWM_IC_CHANNEL_FLOW_METER; /* Get CCR register for the specific Timer and Channel */ capturedValue = HAL_TIM_ReadCapturedValue( htim4, TIM_CHANNEL_4 ); if( capturedValue > lastCapturedValue ) /* Compute the input signal frequency */ delta = capturedValue - lastCapturedValue; else /* Timer counter overflow */ delta = ( 0xFFFF - lastCapturedValue ) + capturedValue; /* Compute the input signal frequency */ inputFrequencyHz = ( 64000000 / delta ); /* Update the last captured value */ lastCapturedValue = capturedValue;}Unfortunately I cannot detect the input frequency.
Is my configuration correct? My main concern is how to compute the right timer frequency in relation to input signal frequency
Thanks for the help!
#input-capture-mode #timer #pwm2017-11-10 12:51 AM
Unfortunately I cannot detect the input frequency.
What does that mean exactly? Is there no interrupt? Have you verified the input signal is present directly on the mcu pin? In the debugger, look at the timer's registers: does CNT change? Does the respective CCR change?
The calculation is better performed as modulo of the period, which in case of 2^N period which is your case reduces to AND.
delta = (capturedValue - lastCapturedValue) & 0xFFFF;
JW
2017-11-10 02:01 AM
Hello,
sorry, I did not express my self.
The IC interrupt is raised, but the computed frequency was wrong.
Now I adjusted the Timer clock frequency to 32 Mhz and I can compute exactly the input signal frequency.
Thanks for the formula, I looking for a better performance formula.
With this formula I can compute the delta in both case: Overflow an no overflow. Using your formula, should be delta an int32_t?
To compute the maximum Timer Frequency I used this formula: f_tim_max < f_signal * 0xFFFF. Am I right?
NOTE regarding the bitwise-and instead of mod:
x modulo y = (x & (y − 1)) - https://stackoverflow.com/questions/6670715/mod-of-power-2-on-bitwise-operators
So your formula should be delta = (capturedValue - lastCapturedValue) & (0xFFFF - 1)
Thanks!
2017-11-10 02:46 AM
No, because the period is ARR+1=0x10000.
JW
2017-11-10 03:50 AM
waclawek.jan wrote:
No, because the period is ARR+1=0x10000.
JW
Which questions do you means?
I set the ARR as 0xFFFF.
Should I delta variable as int16_t?
Thanks
2018-05-13 03:10 AM
Dear Fede
I hope you have solved your problem for a long time.
I produced two tutorials for my students showing how to configure and to use Input Capture technique for measuring signal frequency.
The simplest one is located at
https://community.st.com/0D50X00009bMMADSA4
The second one is more sophisticated and aims at overcoming the limitations of 16 bit timers only available on stm32L0 MCUs :
https://community.st.com/0D50X00009bMMA8SAO
Bye
JC Toussaint
2018-05-13 04:06 AM
Note that timer can be configured to measure frequency itself without any maths. Search datasheet for section 'PWM input mode'. In short: timer do capture event and reset itselfs. With every new measured period timer starts from zero => you dont need calculate diferences of capture events ...
2018-05-13 06:41 AM
timer do capture event and reset itselfs
Not on CH4 - and that's what the original poster wanted to do.
(Note that this is a half-year old thread, just being resurrected by Jean-Christophe - btw. his solution uses the slave-reset too.)
JW