cancel
Showing results for 
Search instead for 
Did you mean: 

Timer 2 - STM32F427ZIT6

Pilous Droip
Senior

Hello.

I try timer 2 on STM32F427 and I have a problem. It ticks too quick.

Here is my system clock. I have external crystal: 25MHz

Clock I want to: 168MHz

void SystemClock_Config(void)
{
	uint32_t i;
 
	  LL_FLASH_SetLatency(LL_FLASH_LATENCY_5);
 
	  if(LL_FLASH_GetLatency() != LL_FLASH_LATENCY_5){}
	  LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1);
	  LL_PWR_DisableOverDriveMode();
	  LL_RCC_HSE_Enable();
 
	   /* Wait till HSE is ready */
	  while(LL_RCC_HSE_IsReady() != 1)
	  { }
	  LL_PWR_EnableBkUpAccess();
	  LL_RCC_ForceBackupDomainReset();
	  LL_RCC_ReleaseBackupDomainReset();
	  LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_HSE);
	  LL_RCC_SetRTC_HSEPrescaler(LL_RCC_RTC_HSE_DIV_25);
	  LL_RCC_EnableRTC();
	  LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_25, 336, LL_RCC_PLLP_DIV_2);
	  LL_RCC_PLL_Enable();
 
	   /* Wait till PLL is ready */
	  while(LL_RCC_PLL_IsReady() != 1)
	  { }
	  LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
	  LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_4);
	  LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_4);
	  LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
 
	   /* Wait till System clock is ready */
	  while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
	  { }
	  LL_Init1msTick(168000000);
	  LL_SYSTICK_SetClkSource(LL_SYSTICK_CLKSOURCE_HCLK);
	  LL_SetSystemCoreClock(168000000);
	  LL_RCC_SetTIMPrescaler(LL_RCC_TIM_PRESCALER_TWICE);
  
	// clock enable
	LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
	LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SYSCFG);
 
	// MCU FLASH
	LL_FLASH_EnablePrefetch();
 
	// 1 msec timer
	Init_Timer2();
}

And timer init is here:

void Init_Timer2(void)
{
	LL_TIM_InitTypeDef TIM_InitStruct = {0};
	LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2);
 
	// 1000 Hz, upcounting 32-bit
	// Fclk = ( 84000000/4 )
	// period = ( Fclk / 21000) = 1000
	TIM_InitStruct.Prescaler         = ((84000000/4)/1000 - 1) ;	// 21000
	TIM_InitStruct.CounterMode       = LL_TIM_COUNTERMODE_UP;
	TIM_InitStruct.Autoreload        = 0xFFFFFFFF;
	TIM_InitStruct.ClockDivision     = LL_TIM_CLOCKDIVISION_DIV4;
	TIM_InitStruct.RepetitionCounter = 0x00;
	LL_TIM_Init(TIM2, &TIM_InitStruct);
 
	LL_TIM_SetClockSource(TIM2, LL_TIM_CLOCKSOURCE_INTERNAL);
	LL_TIM_SetTriggerOutput(TIM2, LL_TIM_TRGO_UPDATE);
	LL_TIM_DisableMasterSlaveMode(TIM2);
 
	LL_TIM_ClearFlag_UPDATE(TIM2);
	LL_TIM_DisableIT_UPDATE(TIM2);
 
	LL_TIM_EnableCounter(TIM2);
}

And system init is here:And I know, that tick of timer is too quick. I measured it (indicatively) 38x. Any idea, what is wrong?

2 REPLIES 2

> TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV4;

This does not do what you may think it does - it is a prescaler for the clocks used in input filters.

JW

Pilous Droip
Senior

Yes. I found this information in datasheet.

Here is function solution:

{	
LL_TIM_InitTypeDef TIM_InitStruct = {0};
 
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2);
 
// 1000 Hz, upcounting 32-bit
// Fclk = ( 42000000 )
// period = ( Fclk / 42000) = 1000 => 1ms
TIM_InitStruct.Prescaler         = 42000 - 1;
TIM_InitStruct.CounterMode       = LL_TIM_COUNTERMODE_UP;
TIM_InitStruct.Autoreload        = 0xFFFFFFFF;
TIM_InitStruct.ClockDivision     = LL_TIM_CLOCKDIVISION_DIV1;
LL_TIM_Init(TIM2, &TIM_InitStruct);
 
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM2);
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM2);
 
LL_TIM_Init(TIM2, &TIM_InitStruct);
 
LL_TIM_ClearFlag_UPDATE(TIM2);
LL_TIM_DisableIT_UPDATE(TIM2);
 
LL_TIM_EnableCounter(TIM2);
}