2014-05-15 08:06 AM
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); }2014-05-15 08:19 AM
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.
2014-05-15 09:42 AM
2014-05-19 07:41 AM
Hi,
Someone can help me?I am stucked on this.Thanks2014-05-19 09:22 AM
''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
2014-05-19 10:17 AM
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 theoverflow 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.2014-05-19 05:47 PM
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, Hal2014-05-19 06:04 PM
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 Felipe2014-05-20 01:23 AM
'' 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.2014-05-20 04:30 AM
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