1
votes

I am using a STM32F401RE board and I want a timer interrupt to happen every X seconds (let's say 60 seconds).

The interrupt callback works. The problem is the interrupt does not happen every 60 seconds (it does every 34 seconds). I have tried different values for prescaler and period but nothing I try is working as I want.

I am using the functions generated by CubeMX in another project:

main.c

TIM_HandleTypeDef htim10;

int main(void)
{
    HAL_Init();

    SystemClock_Config();

    // Some other code

    MX_TIM10_Init();

    HAL_TIM_Base_Start_IT(&htim10);        

    while (1)
    {

    }
}

static void MX_TIM10_Init(void)
{    
    htim10.Instance = TIM10;
    htim10.Init.Prescaler = 35999;
    htim10.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim10.Init.Period = 60000;
    htim10.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    if (HAL_TIM_Base_Init(&htim10) != HAL_OK)
    {
        Error_Handler();
    }
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim->Instance==TIM10)
    {
        printf("ABCDEFG\n\r");
    }
}

void SystemClock_Config(void)
{    
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};

  __HAL_RCC_PWR_CLK_ENABLE();

  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);

  RCC_OscInitStruct.OscillatorType      = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState        = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = 16;
  RCC_OscInitStruct.PLL.PLLState    = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource   = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM        = 16;
  RCC_OscInitStruct.PLL.PLLN        = 288;
  RCC_OscInitStruct.PLL.PLLP        = RCC_PLLP_DIV4;
  RCC_OscInitStruct.PLL.PLLQ        = 6;
  HAL_RCC_OscConfig(&RCC_OscInitStruct);

  RCC_ClkInitStruct.ClockType       = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1);
  RCC_ClkInitStruct.SYSCLKSource    = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider   = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider  = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider  = RCC_HCLK_DIV1;
  if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }

  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

  __HAL_RCC_SYSCFG_CLK_ENABLE();
}

stm32f4xx_hal_msp.c

void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
{
  if(htim_base->Instance==TIM10)
  {
    __HAL_RCC_TIM10_CLK_ENABLE();
    HAL_NVIC_SetPriority(TIM1_UP_TIM10_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn);
  }
}

void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base)
{    
  if(htim_base->Instance==TIM10)
  {
    __HAL_RCC_TIM10_CLK_DISABLE();
    HAL_NVIC_DisableIRQ(TIM1_UP_TIM10_IRQn);   
  } 
}

stm32f4xx_it.c

void TIM1_UP_TIM10_IRQHandler(void)
{
    HAL_TIM_IRQHandler(&htim10);
}

Can anyone explain me what I am doing wrong? How do I configure the timer parameters to achieve the period that I want?

Thank you in advance!

2
Since you don't have a .ioc file, I recommend you start a new, minimalistic project in STM32CubeMx to make one, configure the timer and interrupt as you desire, have it autogenerate the source code, test that it works, then use git difftool and meld to compare your files between what it produces and what you have now. Once you find the differences, come back here and post your solution you found for all to see, and mark your own question as the correct one. I will upvote it. Do you know how to use STM32CubeMX? - Gabriel Staples

2 Answers

1
votes

can you capture your CubeMX's Clock Configuration screen of your project, it make me diagnose your issue easier!

EDIT 1: I check your code, the Timer 10 is run by APB2 clock source so your timer 10's clock is running twice times faster. You should config your code like this:

static void MX_TIM10_Init(void)
{    
    htim10.Instance = TIM10;
    htim10.Init.Prescaler = 35999;
    htim10.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim10.Init.Period = 60000;
    htim10.Init.ClockDivision = TIM_CLOCKDIVISION_DIV2; //TIM_CLOCKDIVISION_DIV1
    if (HAL_TIM_Base_Init(&htim10) != HAL_OK)
    {
        Error_Handler();
    }
}

Frankie

0
votes

add the function below called MX_NVIC_Init(); to the main() function

    static void MX_NVIC_Init(void)
    {
      HAL_NVIC_SetPriority(TIM1_IRQn, 0, 0);
      HAL_NVIC_EnableIRQ(TIM10_IRQn);
    }