cancel
Showing results for 
Search instead for 
Did you mean: 

stm32f407vg input capture problem

mk61
Associate II
Posted on July 27, 2016 at 09:37

Hi. I'm having problem trying to use input capture mode to measure frequency. I create pwn signal from timer4 of microprocessor and try to mesure it's frequency via timer2 input capture. I also measure the frequncy via ossiloscope. The problem is frequencies I measure from ossiloscope an input capture don't match. I have deviation. For higher frequencies higher deviation. For example for 5000Hz I measure 5084,  for 87kHz I measure 131kHz.

My code is below. Pelease help me.

#include <stm32f4xx.h>

uint32_t count;

float frequency;

int main()

{

GPIO_InitTypeDef GPIO_InitStructure;

TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;

TIM_ICInitTypeDef TIM_ICInitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

TIM_OCInitTypeDef TIM_OCInitStructure;

RCC_HSEConfig(RCC_HSE_ON);

while(!RCC_GetFlagStatus(RCC_FLAG_HSERDY));

RCC_SYSCLKConfig(RCC_SYSCLKSource_HSE);

RCC_PCLK2Config(RCC_HCLK_Div1);

RCC_PCLK1Config(RCC_HCLK_Div1);

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);

//Kesme

NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

NVIC_Init(&NVIC_InitStructure);

//GPIOD pwm output

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

GPIO_Init(GPIOD,&GPIO_InitStructure);

GPIO_PinAFConfig(GPIOD,GPIO_PinSource15,GPIO_AF_TIM4);

//GPIOA bit 0 capture input

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

GPIO_Init(GPIOA,&GPIO_InitStructure);

GPIO_PinAFConfig(GPIOA,GPIO_PinSource0,GPIO_AF_TIM2);

//TIMER4  pwm adjustments

TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;

TIM_TimeBaseInitStructure.TIM_Period  = 800/9;

TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInitStructure.TIM_Prescaler = 0;

TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

TIM_OCInitStructure.TIM_Pulse = 40-1;

TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

TIM_OC4Init(TIM4,&TIM_OCInitStructure);

//TIM2 capture adjustments

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_DIV8;

        TIM_ICInitStructure.TIM_ICFilter = 0;

TIM_ICInit(TIM2,&TIM_ICInitStructure);

  

TIM_ClearFlag(TIM2,TIM_FLAG_CC1);

TIM_ITConfig(TIM2,TIM_IT_CC1,ENABLE);

TIM_SetCounter(TIM2,0);

TIM_Cmd(TIM4,ENABLE);

TIM_Cmd(TIM2,ENABLE);

while(1)

{

}

}

void TIM2_IRQHandler()

{

count = TIM_GetCapture1(TIM2);

frequency = 64000000.0/count;

TIM_SetCounter(TIM2,0);

TIM_ClearFlag(TIM2,TIM_FLAG_CC1);

}

3 REPLIES 3
Posted on July 27, 2016 at 10:51

I'd qualify the interrupt source and clear it earlier.

Consider PWM Input mode

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
mk61
Associate II
Posted on August 04, 2016 at 12:31

Thank you clive. I wouldn't guess a floating point division could take  17 cycles. It effects measurement very much. Especially on high frequencies. Now I'm gettin 102kHz instead of 140kHz. Difference is remarkable.

Posted on August 04, 2016 at 12:59

Floating-point constants are double by default, thus the division is performed in double, for which there is no hardware.

Use the f suffix for the constant.

JW