AnsweredAssumed Answered

STM32F4 Problem with Timer OVF

Question asked by Wer.Mark on Oct 19, 2016
Latest reply on Oct 20, 2016 by FTITI.Walid
Hi all,

i have a problem with my program but i can not find the error. Maybe here is one who knows what i'm doing wrong. I want to meassure the time between two edges. I works most of the time, but sometimes the value would be correct just with one OVF two much. So for example (timer runs with 16Mhz) when i meassure 12kHz (via signal generator) most of the time the µC shows the right measurement (1333) but sometimes it shows "66869", so one OVF which shouldn't be there. This happens only, when the value "new" ist exactly "65535". So my thought was that the OVF Interrupt happens before the Capture Interrupt, but normally that shouldn't happen due to the Priority i set? 
Here is my Code: 

void InterruptInit(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  TIM_ICInitTypeDef TIM_ICInitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
 
  // Clock Enable
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
 
  // Clock enable
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
 
  // Config PD13 als Digital-Ausgang
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOD, &GPIO_InitStructure);
 
  // Config des Pins PE11 als AF-Input
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOE, &GPIO_InitStructure);
 
  // Connect PE11 with TIM1 for Input Capture
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource11, GPIO_AF_TIM1);
 
  TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
  TIM_TimeBaseStructure.TIM_Prescaler = 0;           
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
  TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
 
  NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
 
  NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_TIM10_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
 
  // Channel 2
  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 = 0x02;        //0x02 = 4 consecutive events are needed to validate a transition on the output
  TIM_ICInit(TIM1, &TIM_ICInitStructure);
 
  //Interrupt Enable
  TIM_ITConfig(TIM1, TIM_IT_CC2, ENABLE);
  TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
 
  // Timer enable
  TIM_Cmd(TIM1, ENABLE);
}
 
//-----------------
// TIM1 OVF Handler
//-----------------
void TIM1_UP_TIM10_IRQHandler(void)
{
  if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)
  {
    // Delete Interrupt Flags
    TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
 
    OVF_cnt++;
  }
}
 
//-------------------------------
// TIM1 Capture Interrupt Handler
//-------------------------------
void TIM1_CC_IRQHandler(void)
{
  if (TIM_GetITStatus(TIM1, TIM_IT_CC2) != RESET)
  {
    __disable_irq();
 
    // Delete Interrupt Flags
    TIM_ClearITPendingBit(TIM1, TIM_IT_CC2);
 
    uint16_t new = TIM_GetCapture2(TIM1);
    uint8_t OVF = OVF_cnt;
 
    OVF_cnt = 0;
 
    uint32_t period_32 = 0;
 
    period_32 = ((uint32_t)new + (OVF << 16)) - old;
    
    old = new;
    __enable_irq();
  }
}

Thanks in advance
mark

Outcomes