0
\$\begingroup\$

I'm trying to update TIM 2 period but it is not working. MCU is STM32L4 series Timer 6 is configured to trigger an event at every 1ms and Timer 2 is in counter mode which counts number of positive edges on external GPIO.

    // Counter Overflow ISR Handler
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim->Instance == TIM2)
    {
        if(uMode == 0)                                      // Triggers at every 10 counts
        {

            //TIM2->ARR = 99;
            __HAL_TIM_SET_AUTORELOAD(&htim2,99);                // Change period
            uMode = 1;                                      // set mode to 1
            HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET);   // Pin B5 to High
            
        }else if(uMode == 1)                                    // (Should)Triggers at every 100 counts(110 in total)
        {

            HAL_TIM_Base_Stop_IT(&htim2);                       // Stop TIM2 counting
            uMode = 0;                                      // set mode to 0
            HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET); // Pin B5 to High

        }else{
            
        }

    }else if(htim->Instance == TIM6)                            // Triggers at every 1ms
    {
        //TIM2->ARR = 9;
        __HAL_TIM_SET_AUTORELOAD(&htim2,9);                     // Change period
        HAL_TIM_Base_Start_IT(&htim2);                          // Start TIM2 counting

        HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_6);                   // Toggle Pin B6


    }else{

    }
}

However, it always work with period=99 and somehow ignores period=9. Any suggestion why is this the case?

Timer initialization is as below;

static void MX_TIM2_Init(void)
{

  /* USER CODE BEGIN TIM2_Init 0 */

  /* USER CODE END TIM2_Init 0 */

  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};

  /* USER CODE BEGIN TIM2_Init 1 */

  /* USER CODE END TIM2_Init 1 */
  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 0;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 9;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  //htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_ETRMODE2;
  sClockSourceConfig.ClockPolarity = TIM_CLOCKPOLARITY_NONINVERTED;
  sClockSourceConfig.ClockPrescaler = TIM_CLOCKPRESCALER_DIV1;
  sClockSourceConfig.ClockFilter = 0;
  if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM2_Init 2 */

  /* USER CODE END TIM2_Init 2 */

}
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

This maybe a little late for you, but hopefully it will help anyone else reading this at a later time.

In my experience whenever I've seen this happen, I believe (so this may not be correct) that it is because the amount of cycles it takes to process this timer is not enough before another tick occurs (so the timer system gets swamped). It is irrelevant that the timer source is external. This is how the system/compiler looks at it.

Basically means that the timer is too fast for the MCU to manage. I've tried to find ANY STM datasheets, manuals, documents...anything that shows what limitations the timer values have. But never did.

Experimenting with this though, I have slowly increased the timer's period or prescaler until I get a stable output and there definitely is a threshold point for each MCU (also depending on if the timer's output is just a pin or if it has to go through an interrupt and it's code).

This also means that if you need a timer that fast and the system can't produce it, you need either a faster system clock or a faster MCU with a faster system clock. On a 72MHz MCU (STM32F103), I can get a stable 250KHz timer through an interrupt, but not really much faster. If the timer's output is directly to a pin (so not an interrupt that you toggle the pin, but a PWM output), you can get much faster outputs (but I still wouldn't expect more than 1MHz on a STM32F103).

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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