AnsweredAssumed Answered

Counting frequency of input signal - timer counter gives double frequency than external pin interrupt counting

Question asked by neville on Jun 10, 2016
Latest reply on Jun 10, 2016 by Clive One
Hi Guys,

Want to ask for a quick bit of advice please.

I have a STM32F407 running on a board that has been configured to count frequency (number of pulses per second - period and duty cycle are variable).

I had it set up to use the pin that the frequency input was connected to, to trigger an external interrupt and then in the interrupt I would increment a counter. Every 1s the difference between the current counter value and the previous counter value would be output as the frequency during that particular 1s interval.

I recently ran into a problem with the above when presented with very high frequency input signal. The processor was spending too much time interrupting.

I recently changed my code to use the timer with my frequency input signal as external clock signal for the counter.

The problem I am having now is that the new code which uses a timer to count the frequency outputs roughly double the frequency that the previous code based on counting number of external interrupts did. Could anybody help me understand why this is? I checked in DM00031020 STM32 reference manual p589. From what I understand, using ETR external clock only either rising or falling edge can be used, not both. Is there possibly a problem with my previous code that counts on pin external interrupts? Obviously I'm missing something here, I thought that what I was doing in Old code vs New code should give me the same output.

Old previous code for counting external pin interrupts:
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
 
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOD, &GPIO_InitStructure);
 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOD, EXTI_PinSource2);
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
 
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
 
void EXTI0_IRQHandler(void)
{
  u32Total_Counts_C1++;
  EXTI_ClearITPendingBit(EXTI_Line0);
  return;
}

New (problematic) code for counting frequency with timer:
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
 
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_TIM3);
 
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Period = 65535;
TIM_TimeBaseStructure.TIM_Prescaler = 0; //i tried 1 here also, which then gives me ~same frequency as interrupt counting.
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
 
TIM_ETRClockMode2Config(TIM3, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_Inverted, 0x00);
 
TIM_Cmd(TIM3, ENABLE);

Any help/advice appreciated. Thanks for reading.

Outcomes