cancel
Showing results for 
Search instead for 
Did you mean: 

STM32l475RC - TIM3 configuration when running in low power mode

mcoc7n
Associate II

Hi,

in my Project I need a millisecond timer. Therefore I try to use TIM3. Now I have the following problem.

For example, when the MCU runs in Run-Mode at 80 MHz TIM3 fires every 1 ms according to its configuration. But when the MCU runs in low power mode at 2 MHz, TIM3 fires at a too low frequency (around a factor of 3). After studying the datasheet and testing around with the configuration, I have no idea what it is. I think the configuration should be ok.

What am I doing wrong? Does somebody has any idea?

Here is my configuration of the system clocks.

void g_system_clock_config_lowpower(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
 
  // Reset the RCC clock configuration to the default reset state.
  HAL_RCC_DeInit();
 
  /** Configure LSE Drive Capability
  */
  HAL_PWR_EnableBkUpAccess();
  __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE|RCC_OSCILLATORTYPE_MSI;
  RCC_OscInitStruct.LSEState = RCC_LSE_ON;
  RCC_OscInitStruct.MSIState = RCC_MSI_ON;
  RCC_OscInitStruct.MSICalibrationValue = 0;
  RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_5;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_LPUART1
                              |RCC_PERIPHCLK_I2C1|RCC_PERIPHCLK_ADC;
  PeriphClkInit.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_SYSCLK;
  PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_SYSCLK;
  PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_SYSCLK;
  PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure the main internal regulator output voltage
  */
  if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
  {
    Error_Handler();
  }
  /** Enable MSI Auto calibration
  */
  HAL_RCCEx_EnableMSIPLLMode();
 
  /* Update SystemCoreClock variable */
  SystemCoreClockUpdate();
 
}

And this is my configuration of TIM3.

void MX_TIM3_Init(void)
{
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
 
  uint32_t uwPrescalerValue = (uint32_t)(SystemCoreClock / 100000) - 1; // to 100 kHz
  uint32_t period = 100-1; // to 1 kHz -> 1/1000s = 0.001s
 
  htim3.Instance = TIM3;
  htim3.Init.Prescaler = uwPrescalerValue;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = period;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
}

Thanks in advance,

Marco.

1 ACCEPTED SOLUTION

Accepted Solutions

System clock other than you thought? Output it 8

to MCO pin and measure.

Timer misconfiguration? Read out TIM registers and check/post.

ISR execution takes too long? Stop it down to bare minimum, toggle pin at entry and exit and measure.

JW

View solution in original post

2 REPLIES 2

System clock other than you thought? Output it 8

to MCO pin and measure.

Timer misconfiguration? Read out TIM registers and check/post.

ISR execution takes too long? Stop it down to bare minimum, toggle pin at entry and exit and measure.

JW

mcoc7n
Associate II

Thanks for the tips. After checking the three points you mentioned, I could solve it.

The problem was "hidden" in the main loop.

There were two short sections of code that should be executed atomically. For this purpose, the interrupts were deactivated before the execution of the code section and reactivated after execution. Finally this led to the described problem.