cancel
Showing results for 
Search instead for 
Did you mean: 

Frequency Meansure

felipe
Associate II
Posted on May 15, 2014 at 17:06

Hi,  I am using uvision4 with stm32f1xx to meansure frequency counting the time of the falling edge pulse. I need a high precision to meansure frequency from 0Hz to 240Hz. The first thing that I do was to set the prescaler to mensure 240Hz. That is ok, the problem is that I cant get when the timer count overflow to mensure frequency from 61 to 0. The program enter in theTIM_IT_Update all the time, what am I doing wrong?     void RCC_Configuration(void){

/* TIM2 clock enable */

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); TIM_TimeBaseStructure.TIM_Period = 65535; //20 mS

TIM_TimeBaseStructure.TIM_Prescaler = Prescaler_Pickup - 1; //1 uS 1 MHz

TIM_TimeBaseStructure.TIM_ClockDivision = 0;

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

}   void TIM2_IRQHandler (void) {

if(TIM_GetITStatus(TIM2, TIM_IT_CC1) == SET){

/* Clear TIM3 Capture compare interrupt pending bit */

TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);

if(CaptureNumber == 0){

/* Get the Input Capture value */

IC3ReadValue1 = TIM_GetCapture1(TIM2);

CaptureNumber = 1;

estourou_timer = 0;

}

else if(CaptureNumber == 1){

/* Get the Input Capture value */

IC3ReadValue2 = TIM_GetCapture1(TIM2);

/* Capture computation */

if (IC3ReadValue2 > IC3ReadValue1){

Capture = (estourou_timer * 65535) + (IC3ReadValue2 - IC3ReadValue1);

}

else{

Capture = (estourou_timer * 65535) + ((0xFFFF - IC3ReadValue1) + IC3ReadValue2);

}

/* Frequency computation */

Pickup_1_FLOAT = (float) (72000000/Prescaler_Pickup) / Capture;

if(Pickup_1_FLOAT < Menor_Med) Menor_Med = Pickup_1_FLOAT;

CaptureNumber = 0;

}

}

if((TIM_GetITStatus(TIM2, TIM_IT_Update) == SET )){ //overflow

TIM_ClearITPendingBit(TIM2, TIM_FLAG_Update);

estourou_timer++;

}

}   void TIM2_Configuration(){

TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;

TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;

TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;

TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;

TIM_ICInitStructure.TIM_ICFilter = 0x0;

TIM_ICInit(TIM2, &TIM_ICInitStructure); /* TIM enable counter */

TIM_Cmd(TIM2, ENABLE);

/* Enable the CC1 Interrupt Request */

TIM_ITConfig(TIM2, TIM_IT_CC1 | TIM_IT_Update, ENABLE);

TIM_ICInit(TIM2, &TIM_ICInitStructure); /* TIM enable counter */

TIM_Cmd(TIM2, ENABLE);    /* Enable the TIM3 global Interrupt */  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQChannel;  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  NVIC_Init(&NVIC_InitStructure);      }      

20 REPLIES 20
Posted on May 15, 2014 at 17:19

I swear I get the felling of DejaVu

The math here is totally broken:

/* Capture computation */
if (IC3ReadValue2 > IC3ReadValue1){
Capture = (estourou_timer * 65535) + (IC3ReadValue2 - IC3ReadValue1);
}
else{
Capture = (estourou_timer * 65535) + ((0xFFFF - IC3ReadValue1) + IC3ReadValue2);
}

I'm not going to look at this without a complete stand-alone example, where all the defines and variables are present in a fashion that can be compiled.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
felipe
Associate II
Posted on May 15, 2014 at 18:42

Clive1,

Sorry I forget to say that I just take the example STM32F10x_StdPeriph_Examples\TIM\InputCapture.

The math is the same, I just put (estourou_timer * 65535) to sum the overflow time to compute low frequency.

My problem is detecting the overflow as a sad.

felipe
Associate II
Posted on May 19, 2014 at 16:41

Hi,

Someone can help me?

I am stucked on this.

Thanks
chen
Associate II
Posted on May 19, 2014 at 18:22

''Someone can help me?

I am stucked on this.'' ''

I need a high precision to meansure frequency from 0Hz to 240Hz.

'' How is this high precision? 240Hz is hardly a high freq Do you need to know the fractional part of the frequency to a high degree of accuracy? Or just work out the frequency to the nearest Hz? In any case, you are going about it the hard way. 2 simple ways to do it : 1) Set up EXTI to count rising/falling edges, set up timer to capture count at known period and calculate the freq 2) set up one timer as a counter clocked by external freq, set up 2nd timer to capture count at known period and calculate the freq
felipe
Associate II
Posted on May 19, 2014 at 19:17

Hi,

Thanks for the reply.

I need to know the fractional part of the frequency.

1) Set up EXTI to count rising/falling edges, set up timer to capture count at known period and calculate the freq.

I am already doing it. 

My question is how can I use the

overflow flag

so I can ready low frequency (summing the overflow to my ''known period'').

2)

I know that I can use 2 timers and do a 32bit timer, but it will cost me hardward changes and programming time because I didnt find a example code.

raptorhal2
Lead
Posted on May 20, 2014 at 02:47

For each overflow, add 65536 to the timer count, obviously a 32 bit or longer integer.

You have to decide how low in frequency you wish to go. You can't wait forever for a pulse, and the timer overflows eventually overflow a 32 bit count. When you have waited as long as you can, declare the result to be zero frequency.

Cheers, Hal

felipe
Associate II
Posted on May 20, 2014 at 03:04

Hal,

Thank you for the reply.

I understand what you sad, but it is another problem.

The problem I am trying to resolve is that I cant get the overflow flag.

So I didnt know when the overflow happen.

Luis Felipe

chen
Associate II
Posted on May 20, 2014 at 10:23

'' is how can I use the

overflow flag

''

What overflow flag?

Your problem is that you have chosen to do this in a really hard way.

Do not use the general timer (TIM2) - use the 32bit Timer (TIM1)

Set this to a known high(ish) freq (calibrate it)

Then just capture the 32 bit count.

Use this to do the maths - it is EASIER.

''I didnt find a example code.''

For what you are doing - it is unlikely you will find an exact example.

You are going to have to do some work and write your won code.

felipe
Associate II
Posted on May 20, 2014 at 13:30

Hi,

Thanks for the help again. I have to do in this way because I am using 3 differents types of meters (project requirement) and I desagree with you when you say hard way. In my head it is so simple, I just have problem with knowing that the timer had an overflow! The overflow flag that I am talking is referenced in TIMx_SR in theRM0008 -Reference manual page Bit 0 UIF: Update interrupt flagThis bit is set by hardware on an update event. It is cleared by software.0: No update occurred.1: Update interrupt pending. This bit is set by hardware when the registers are updated:

–At overflow or underflow regarding the repetition counter value (update if repetition

counter = 0) and if the UDIS=0 in the TIMx_CR1 register.–When CNT is reinitialized by software using the UG bit in TIMx_EGR register, if URS=0and UDIS=0 in the TIMx_CR1 register.–When CNT is reinitialized by a trigger event (refer to Section 4.3: TIM1&TIM8 slavemode control register (TIMx_SMCR)), if URS=0 and UDIS=0 in the TIMx_CR1 register. I try to do in this way (after the Compare/Capture mode configurated as in the example of ST lib said in previous post):

if((TIM_GetITStatus(TIM2, TIM_IT_Update) == SET )){ //overflow
TIM_ClearITPendingBit(TIM2, TIM_FLAG_Update);
estourou_timer++;

}

and I have tried in this way too:

if ((TIM2->SR & 0x0001) != 0){
estourou_timer++;
TIM2->SR &= ~(1<<0); 
}

But the processor keep entering in the braces in frequencies that no overflow occur. How I know that overflow is not occurring? I use the Prescaler in 18, so: Clock frequency: 72Mhz/18 =4 Mhz. Time of overflow: (1/4Mhz)*65535 = 16,38ms

Frequency when overflow start:

1/16,38ms = 61Hz to 0Hz