2015-03-18 05:44 AM
Hello,
I'd like to use channel 2 and channel 4 of TIM2 as input capture. Channel 2 work fine, but channel seems returning the timer counter. Here's the code:
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM16, ENABLE);
/*Trigger pin configuration*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource4, GPIO_AF_1);
TIM_TimeBaseStructure.TIM_Prescaler = 71;
TIM_TimeBaseStructure.TIM_Period = 60000;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM16, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OC1Init(TIM16, &TIM_OCInitStructure);
TIM_CtrlPWMOutputs(TIM16, ENABLE);
TIM_Cmd(TIM16, ENABLE);
TIM_SetCompare1(TIM16, 10);
/*Echo Pin configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource4, GPIO_AF_2);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
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 = 0x0;
TIM_PWMIConfig(TIM2, &TIM_ICInitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource11,GPIO_AF_1);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;
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 = 0x0;
TIM_PWMIConfig(TIM2, &TIM_ICInitStructure);
TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2);
TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);
TIM_SelectMasterSlaveMode(TIM2,TIM_MasterSlaveMode_Enable);
TIM_Cmd(TIM2, ENABLE);
#clive1
2015-03-28 06:24 AM
Hi, I assigned the period of timer 2 interrupt to 0xFFFFFFFF and the prescaler 0. While in the interrupt, I put the coding below. Is it correct?
cc[0] = TIM_GetCapture2(TIM2)/72;
delta[0] = cc[0] - cc[1];
cc[1] = cc[0];
2015-03-28 06:46 AM
What part are we talking about in this thread? The STM32F3?
I wouldn't do the division at that point a) it loses all the precision you have, and b) interferes with the numbers wrapping in the 32-bit space during the subtraction. This would measure the periodicity between two edges, either rising, falling, or both, depending on how you configured the timer. To measure frequency and duty you'd need to be observing both edges. and making three consecutive measurements.2015-03-28 07:03 AM
Ya, it is STM32F3. May you show me where should I do the division?
Measurement at the rising edge, falling edge?2015-03-28 07:28 AM
With integer math you'd usually want to do any division last, so as to maintain precision, as you're about to throw away the fractional portion.
cc[0] = TIM_GetCapture2(TIM2);
delta[0] = (cc[0] - cc[1]) / 72; // time between two measurements in microseconds, from 72 MHz clock
cc[1] = cc[0];
2015-03-28 07:38 AM
With rounding
delta[0] = ((cc[0] - cc[1]) + 36) / 72;
2015-03-28 08:32 AM
Thanks clive. You said that I have to measure 3 consecutive values to get duty and frequency. The timer interrupt is executed every time the timer overflow as the period is set to 0xFFFFFFFF. so how can I observe both edges and make 3 measurements.
2015-03-28 03:58 PM
Sounds like you've got the wrong interrupt enabled. I'd really like not to have to code your project for you.