AnsweredAssumed Answered

Input capture interrupts ignored

Question asked by bonelli.fabio on Jun 29, 2017
Latest reply on Jul 3, 2017 by bonelli.fabio

I'm using stm32f767NI.

I need to use a timer in input capture mode, but I would like to adapt the prescaler to the input frequency.

So I set the same channel of the timer in TimeBase mode to catch overflows and in Input Capture mode to have frequency estimation. If I have more than two overflows, I calcule the prescaler on the numbers of overflows.

I fix the input frequency on 15kHz and I have 14400 counts between two rising edges of the signal, but sometimes I have 28800 counts. Sometimes one capture interrupt is ignored.

These are the two interrupt routines:

Overflows interrupt routine:

    __HAL_TIM_CLEAR_IT(&(timDrvInst[TIM8_INST].timInst), TIM_IT_UPDATE);    
     timDrvInst[TIM8_INST].ICOverflows++;

Input Capture interrupt routine:

     __HAL_TIM_CLEAR_IT(&(timDrvInst[TIM8_INST].timInst), TIM_IT_CC3);
     timDrvInst[TIM8_INST].timInst.Channel = HAL_TIM_ACTIVE_CHANNEL_3;
    HAL_TIM_IC_CaptureCallback(&(timDrvInst[TIM8_INST].timInst));
    timDrvInst[TIM8_INST].timInst.Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;

Initialization of the timer:

    TIM_IC_InitTypeDef     sICConfig;
  /* Set TIMx instance */
  timDrvInst[*instInd].timInst.Instance = tim;

 

  /* Initialize TIMx peripheral as follows:
       + Period = 0xFFFF
       + Prescaler = 0
       + ClockDivision = 0
       + Counter direction = Up
  */
  timDrvInst[*instInd].timInst.Init.Period            = 0xFFFF;
  timDrvInst[*instInd].timInst.Init.Prescaler         = 0;
  timDrvInst[*instInd].timInst.Init.ClockDivision     = 0;
  timDrvInst[*instInd].timInst.Init.CounterMode       = TIM_COUNTERMODE_UP;
  timDrvInst[*instInd].timInst.Init.RepetitionCounter = 0;
    
    if (HAL_TIM_Base_Init(&(timDrvInst[*instInd].timInst)) != HAL_OK)
  {
    /* Initialization Error */
    return RET_TIM_INIT_ERROR;
  }

 

  /*##-2- Start the TIM Base generation in interrupt mode ####################*/
  /* Start Channel1 */
  if (HAL_TIM_Base_Start_IT(&(timDrvInst[*instInd].timInst)) != HAL_OK)
  {
    /* Starting Error */
    return RET_TIM_INIT_ERROR;
  }
  HAL_TIM_IC_MspInit(&(timDrvInst[*instInd].timInst));

  sICConfig.ICPolarity  = TIM_ICPOLARITY_RISING;
  sICConfig.ICSelection = TIM_ICSELECTION_DIRECTTI;
  sICConfig.ICPrescaler = TIM_ICPSC_DIV1;
  sICConfig.ICFilter    = 0;
    //Inizializzo meanDiv, cioè il il numero di ingressi per calcolare un perdiodo medio
    timDrvInst[*instInd].meanDiv = 1;
  if(HAL_TIM_IC_ConfigChannel(&(timDrvInst[*instInd].timInst), &sICConfig, chan) != HAL_OK)
  {
    /* Configuration Error */
    return RET_TIM_INIT_ERROR;
  }
  /*##-3- Start the Input Capture in interrupt mode ##########################*/
  if(HAL_TIM_IC_Start_IT(&(timDrvInst[*instInd].timInst), chan) != HAL_OK)
  {
    /* Starting Error */
    return RET_TIM_INIT_ERROR;
  }  

void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim) 

{

        GPIO_InitTypeDef   GPIO_InitStruct;
            /* Configure  (TIMx_Channel) in Alternate function, push-pull and high speed */
        GPIO_InitStruct.Pin = GPIO_PIN_7;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_PULLUP;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF3_TIM8;
        HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
        /* Enable GPIO channels Clock */
        __HAL_RCC_GPIOI_CLK_ENABLE();

 

        __HAL_RCC_TIM8_CLK_ENABLE();
        HAL_NVIC_SetPriority(TIM8_CC_IRQn, 3, 0);

 

        /* Enable the TIMx global Interrupt */
        HAL_NVIC_EnableIRQ(TIM8_CC_IRQn);    

}

void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{
        __HAL_RCC_GPIOI_CLK_ENABLE();

 

        __HAL_RCC_TIM8_CLK_ENABLE();        
        HAL_NVIC_SetPriority(TIM8_UP_TIM13_IRQn, 4, 1);

 

        /* Enable the TIMx global Interrupt */
        HAL_NVIC_EnableIRQ(TIM8_UP_TIM13_IRQn);
}

 

 

What is wrong?

Outcomes