2012-04-17 06:01 AM
Hi,
I want to capture a signal with 30Hz frequency by a timer input capture. The timer is already working but the measured frequency is not 30Hz. I always measure a frequency of 29.85Hz or 30.3Hz. Are there any mistakes according to may selected period or prescaler values? By the way I`m using the STM32F103XC processor.void TIMER_InitInputCaptureTimer(TIM_TypeDef* TIMx, unsigned short tmrchannel, unsigned short period)
{ TIM_ICInitTypeDef TIM_ICInitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; unsigned short PrescalerValue = (unsigned short) (SYSTEM_TIMERCLOCK / TIMER_TAKT) - 1;TIM_TimeBaseStructure.TIM_Period = period -1; //65535;
TIM_TimeBaseStructure.TIM_Prescaler = (TIMER_TAKT - 1); //0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIMx, &TIM_TimeBaseStructure);TIM_PrescalerConfig(TIMx, PrescalerValue, TIM_PSCReloadMode_Immediate);
TIM_ICInitStructure.TIM_Channel = tmrchannel; //TIM_Channel_3;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; // Div:1, every edge TIM_ICInitStructure.TIM_ICFilter = 0x3; TIM_ICInit(TIMx, &TIM_ICInitStructure);/* Enable the CC3 Interrupt Request */
TIM_ClearITPendingBit(TIM1, tmrchannel); //TIM_IT_CC3); TIM_ITConfig(TIMx, tmrchannel, ENABLE);}
void TIMER_Init(TIM_TypeDef* TIMx, unsigned char mode, unsigned short tmrchannel, unsigned char irqchannel,
unsigned short period, unsigned short fps) { NVIC_InitTypeDef NVIC_InitStructure;switch(mode)
{ case TMR_MODE_UPD: TIMER_InitUpdTimer(TIMx, tmrchannel, fps); break;case TMR_MODE_INPUTCAPTURE:
TIMER_InitInputCaptureTimer(TIMx, tmrchannel, period); break;default:
return; } NVIC_InitStructure.NVIC_IRQChannel = irqchannel; //TIM1_CC_IRQChannel; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } And that`s my call of the timer function: volatile unsigned short IC3ReadValue1 = 0, IC3ReadValue2 = 0; volatile unsigned short CaptureNumber = 0; volatile unsigned int Capture = 0; volatile unsigned int TIM1Freq = 0; int d2i(float d) { float value; value = d; value /= 10; value += 0.5; return value; } TIMER_Init(TIM1, TMR_MODE_INPUTCAPTURE, TIM_Channel_3, TIM1_CC_IRQChannel, 64800, 0); TIM_Cmd(TIM1, ENABLE); My Interrupt ISR:void TIM1_CC_IRQHandler (void)
{ TIM1->SR & TIM_IT_CC3) { /* capture timer */ //clear pending bit TIM1->SR = (unsigned short)~TIM_FLAG_CC3;if(CaptureNumber == 0)
{ /* Get the Input Capture value */ IC3ReadValue1 = TIM1->CCR3; CaptureNumber = 1; } else if(CaptureNumber == 1) { /* Get the Input Capture value */ IC3ReadValue2 = TIM1->CCR3;/* Capture computation */
if (IC3ReadValue2 > IC3ReadValue1) { Capture = (IC3ReadValue2 - IC3ReadValue1); } else { Capture = ((0xFFFF - IC3ReadValue1) + IC3ReadValue2); } /* Frequency computation */ TIM1Freq = d2i ((float)(2 * TIMER_TAKT * 10 / Capture));CaptureNumber = 0;
}/* flag: new rising edge interrupt INTR received */
captureFlag++; /* clear all flags */ TIM1->SR = ~0xFF; } } I hope someone of you could give me some hints to measure the exact frequency of the input signal. best regards Hans2013-02-27 11:09 PM
Hi Clive:
After searching in the NET i found this example but also we have a problem the results are not Ok .the code: TIM_DeInit(TIM3 ); /* TIM3 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); /* GPIOC clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOC, &GPIO_InitStructure);GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_0 );GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_0 ); GPIO_PinAFConfig(GPIOC, GPIO_PinSource8, GPIO_AF_0 ); GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_0 ); /* Enable capture*/ TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0; TIM_ICInit(TIM3, &TIM_ICInitStructure); TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; 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 = 0; TIM_ICInit(TIM3, &TIM_ICInitStructure); TIM_ICInitStructure.TIM_Channel = TIM_Channel_3; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInit(TIM3, &TIM_ICInitStructure); TIM_ICInitStructure.TIM_Channel = TIM_Channel_4; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling; TIM_ICInit(TIM3, &TIM_ICInitStructure); /* Enable TIM3 */ TIM_Cmd(TIM3, ENABLE); /* Enable CC1-4 interrupt */ TIM_ITConfig(TIM3, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE); /* Clear CC1 Flag*/ TIM_ClearFlag(TIM3, TIM_FLAG_CC1 | TIM_FLAG_CC2 | TIM_FLAG_CC3 | TIM_FLAG_CC4 ); NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority=2; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);} void TIM3_IRQHandler() { TIM_ICInitTypeDef TIM_ICInitStructure; if (TIM3 ->SR & TIM_IT_CC1 ) { TIM3 ->SR &= (~TIM_IT_CC1 ); if (pulseState == 0) { TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling; // Any time we get a rising edge on CH1, we reset the counter. All channels are // phase aligned, so they all use this as a reference. TIM_SetCounter(TIM3,0); } else { TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; // Pull the value on the falling edge. ccr[0] = TIM_GetCapture1(TIM3 ); } pulseState = !pulseState; // Reverse polarity. TIM_ICInit(TIM3, &TIM_ICInitStructure); } if (TIM3 ->SR & TIM_IT_CC2 ) { TIM3 ->SR &= (~TIM_IT_CC2 ); ccr[1] = TIM_GetCapture2(TIM3 ); } if (TIM3 ->SR & TIM_IT_CC3 ) { TIM3 ->SR &= (~TIM_IT_CC3 ); ccr[2] = TIM_GetCapture3(TIM3 ); } if (TIM3 ->SR & TIM_IT_CC4 ) { TIM3 ->SR &= (~TIM_IT_CC4 ); ccr[3] = TIM_GetCapture4(TIM3 ); }}