Skip to main content
Pilous Droip
Senior
April 1, 2019
Question

Timer 2 - STM32F427ZIT6

  • April 1, 2019
  • 2 replies
  • 956 views

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?

This topic has been closed for replies.

2 replies

waclawek.jan
Super User
April 2, 2019

> 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
April 3, 2019

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);
}