0
\$\begingroup\$

I'm trying to use timer2 in STM32L475 but it doesn't start firing the interrupt at all.

I would like to configure the timer for a minute.

void InitializeTimer()
{
    TIM_SlaveConfigTypeDef sSlaveConfig;
  TIM_MasterConfigTypeDef sMasterConfig;

  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 10000;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 500;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
  {
          _Error_Handler(__FILE__, __LINE__);
  }

  sSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET;
  sSlaveConfig.InputTrigger = TIM_TS_ITR0;
  if (HAL_TIM_SlaveConfigSynchronization(&htim2, &sSlaveConfig) != HAL_OK)
  {
          _Error_Handler(__FILE__, __LINE__);
  }

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  {
          _Error_Handler(__FILE__, __LINE__);
  }


if(HAL_TIM_Base_Start_IT(&htim2) != HAL_OK)
{
  _Error_Handler(__FILE__, __LINE__);
}

}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == TIM2) {
          start_processing = true;

    }
}

void TIM2_IRQHandler()
{
    /* Clear interrupt flag first. It cannot be the last instruction in an interrupt handler. */
     __HAL_TIM_CLEAR_FLAG(&htim2, TIM_FLAG_UPDATE);            //clear interrupt flag
    start_processing = true;
}

before main loop:

 MX_I2C3_Init();
  InitializeTimer();
  //MX_SPI3_Init();
  HAL_NVIC_SetPriority(TIM2_IRQn, 0, 1);
  HAL_NVIC_EnableIRQ(TIM2_IRQn);// Enable interrupt from TIM3 (NVIC level)
\$\endgroup\$
  • \$\begingroup\$ Some things to check: Does it start counting and reach the limit? What is the master timer (TIM1?) doing? Does it work without the master-slave configuration? Is start_processing declared as volatile? What do the control and status registers contain? \$\endgroup\$ – berendi Jun 5 at 10:16
  • \$\begingroup\$ @berendi yes start_processing declared as volatile. Can you show a basic setup without master and slave ? \$\endgroup\$ – Andre Jun 5 at 10:26
  • \$\begingroup\$ @berendi HAL_TIM_PeriodElapsedCallback is never called \$\endgroup\$ – Andre Jun 5 at 10:27
  • \$\begingroup\$ The period value seems to be way too low for one minute. Does the controller run in some reduced frequency (low power) mode? \$\endgroup\$ – berendi Jun 5 at 11:30
0
\$\begingroup\$

HAL_TIM_PeriodElapsedCallback() is never called because there is no code to call it. It is supposed to be called from TIM2_IRQHandler().

Here is a basic timer setup with interrupts every minute, assuming the APB1 clock is 80 MHz.

volatile int start_processing;
void TIM2_IRQHandler(void) {
    if(TIM2->SR & TIM_SR_UIF) {    // check status
        start_processing = 1;
        TIM2->SR &= ~TIM_SR_UIF;   // clear status
    }
}

void InitializeTimer(void) {
    RCC->APB1ENR1 |= RCC_APB1ENR1_TIM2EN;
    RCC->APB1ENR1;
    TIM2->PSC = 9999;           // 80 MHz clock is prescaled to 8 kHz
    TIM2->EGR = TIM_EGR_UG;     // required to take over the ARR value
    TIM2->ARR = 479999;         // 8000 * 60 - 1
    TIM2->DIER = TIM_DIER_UIE;  // enable update (timer overflow) interrupt
    TIM2->CR1 = TIM_CR1_CEN;    // start timer
    NVIC_SetPriority(TIM2_IRQn, 0);
    NVIC_EnableIRQ(TIM2_IRQn);
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.