1
\$\begingroup\$

I bought an STM32L433 Nucleo-64 board (STM32L433RCTxP) and I am trying to learn more about the LPTIM peripheral. I am experimenting with setting up the LPTIM1 peripheral so that it generates an interrupt every 1 second, and the LPTIM1 interrupt handler would do some trivial task.

This is how I am setting up my LPTIM1:

/* Note: SYSCLK, HCLK, PCLK1, PCLK2 are all 16MHz running on HSI */
static void MX_LPTIM1_Init(void)
{
  hlptim1.Instance = LPTIM1;
  hlptim1.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;
  hlptim1.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV128;
  hlptim1.Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE;
  hlptim1.Init.OutputPolarity = LPTIM_OUTPUTPOLARITY_HIGH;
  hlptim1.Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE;
  hlptim1.Init.CounterSource = LPTIM_COUNTERSOURCE_INTERNAL;
  hlptim1.Init.Input1Source = LPTIM_INPUT1SOURCE_GPIO;
  hlptim1.Init.Input2Source = LPTIM_INPUT2SOURCE_GPIO;
  if (HAL_LPTIM_Init(&hlptim1) != HAL_OK)
  {
    Error_Handler();
  }

  HAL_NVIC_SetPriority(LPTIM1_IRQn, 1, 0);
  HAL_NVIC_EnableIRQ(LPTIM1_IRQn);

  /* 65535 is the value loaded into LPTIM1's ARR register */
  HAL_LPTIM_Counter_Start_IT(&hlptim1, 65535);
}

The interrupt handler currently looks like this:

static uint32_t counter = 0;

/**
  * @brief  Autoreload match callback in non blocking mode 
  * @param  hlptim : LPTIM handle
  * @retval None
  */
void HAL_LPTIM_AutoReloadMatchCallback(LPTIM_HandleTypeDef *hlptim)
{
    /* Blink onboard LED */
    if(counter >= 2)
    {
        /* TODO: Do some task here */
        DoRandomStuffHere();
        
        counter = 0;
    }
    
    counter++;
}

The code above does not produce an interrupt every 1 second, but the function DoRandomStuffHere() does get executed almost every second. I measured the timing with a stopwatch and the function seems to execute periodically at slightly higher than 1Hz (maybe at around 0.9 seconds between each execution).

I am wondering what the equation looks like for the LPTIMx peripherals. I thought it was similar to TIMx timer peripherals where:

TIMx_Frequency = SYSCLK/((Period + 1) * (Prescaler + 1))

and the Period = value that goes into ARR. If I were to use this formula for the LPTIM1, it does not come close to the 1Hz I am expecting.

What sort of parameters would I need to generate an LPTIM1 interrupt every second? Thanks!

For comparison, I have also included code where the TIM2 generates an interrupt every second:

/**
  * @brief TIM2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM2_Init(void)
{
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};

  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 15999;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 999;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  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();
  }

  HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(TIM2_IRQn);

  /* Start TIM2 Interrupt - 1sec interrupt */
  HAL_TIM_Base_Start_IT(&htim2);
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim->Instance == TIM2)
    {
      /* TODO: Do some task here */
      DoRandomStuffHere();
    }
}
\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

I obtained the equation from a different Q&A forum, and the update rate (in Hz) is: \begin{equation} UpdateRate_{LPTIM} = \frac{ClockSource}{(Prescaler)(ARR + 1)} \end{equation} Based on the equation above, I should be getting an update rate of 1.9Hz, so I will double-check my measurements with a Logic Analyzer (at 1.9Hz, DoRandomStuffHere() should be executing periodically and slower than 1 second in between each function execution).

In the code above, the only way to slow it down is to change the clock source's frequency or to use a different clock source that is slower (such as internal LSI).

\$\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.