2016-08-04 08:11 AM
Timer3 runs 2x faster than expected
I know what many readers are thinking but read onI set my STM32F746 (DISCOVERY PCB) for SysClk=216 MHzAHB Prescaler set to �1 thus HCLK = 216 MHzAPB1 prescaler set to �4 thus PCLK1 = 54 MHz & APB1 timer clocks are 108 MHzAPB2 prescaler set to �2 thus PCLK2 = 108 MHz & APB2 timer clocks are 216 MHz (RCC_CFGR: PPRE2=4 and PPRE1=5 -- I checked)Timer3 is on APB1 thus its input clocking is 108 MHzUnless my understanding is bad, its CK_PSC is also 108 MHzThen setting TIM3_PSC to 1 (�2) CK_CNT = 54 MHzThen setting the auto reload register (TIM3_ARR) to 54000 should set the UIF bit in TIM2_SR at 1 KHz.I use Timer3 / ISR to make a 1 kHz up-counter in RAM.But the damn thing up-counts at 2 kHz. Setting TIM3_PSC to 3 (�4) gives me my desired interrupt rate. Thus I have a workaround.As a sanity check I used the ARM 24-bit timer running at HCLK (no �8) with 0xFFFFFF reload also performing a RAM increment. I did this running a while(1) which, because I prefer assembly, was written as �b .�In 60 seconds (eyeball on a sweep second hand) I got 744 ARM timer counts while I got 120338 �millisecond� interrupts. The count of 744 ARM timer interrupts is well within error limits for pressing pause on the debugger. FWIW, caching is disabled by reset and any existing cache has been scrubbed.Clearly I misunderstood something. But what? #stm32f746-discovery #timer2016-08-04 08:22 AM
''2. When TIMPRE bit of the RCC_DKCFGR1 register is reset, if APBx prescaler is 1, then TIMxCLK = PCLKx, otherwise TIMxCLK = 2x PCLKx.
3. When TIMPRE bit in the RCC_DCKCFGR1 register is set, if APBx prescaler is 1,2 or 4, then TIMxCLK = HCLK, otherwise TIMxCLK = 4x PCLKx''
2016-08-04 10:53 AM
From the same Reference manual section 5.3.25:
RCC_DKCFGR1 Bit 24 TIMPRE: Timers clocks prescalers selection:This bit is set and reset by software to control the clock frequency of all the timers connected to APB1 and APB2 domain.0: If the APB prescaler (PPRE1, PPRE2 in the RCC_CFGR register) is configured to a division factor of 1, TIMxCLK = PCLKx. Otherwise, the timer clock frequencies are set to twice to the frequency of the APB domain to which the timers are connected: TIMxCLK = 2xPCLKx.1:If the APB prescaler (PPRE1, PPRE2 in the RCC_CFGR register) is configured to a division factor of 1, 2 or 4, TIMxCLK = HCLK. Otherwise, the timer clock frequencies are set to four times to the frequency of the APB domain to which the timers are connected: TIMxCLK = 4xPCLKx.Yes, that would do it if RCC_DKCFGR1 did not have a reset value of 0x00000000. But it does and I did not change it. While looking for an answer on my own I found section 5.3.25. I then looked at RCC_DKCFGR1 using the IAR debugger via ST-LINK. It was at its reset value.Hardware bug? Documentation error? Or something else?2018-12-17 04:32 PM
Sorry to bring this up after so long but I am seeing exactly the same behaviour as OP when TIMPRE is reset, my SYSCLK is 160MHz from the PLL, and my HCLK (Prescaler 4), PCLK (Prescaler 4) are all 40MHz. I am working with a STM32F746NG.
If TIMPRE is set, I expect the frequency of the clock to be 40MHz (HCLK), (Timer set to PSC 39, ARR, 4999) I checked and it works fine, I see 5ms interrupts.
If TIMPRE is reset, I expect the frequency to be twice the PCLK, so 80MHz, (Timer set to PSC 79, ARR 4999) I would say the timer in this case goes twice as slow, if I set the PSC to 19 it seems to work fine, but this would mean a PCL of 20MHz if I understand it right.
So basically, what is the clock frequency of the timers when TIMPRE is reset in this scenario, 2xPCLK is 80MHz or 20MHz? I would appreciate some clarification, I am clearly missing something. Thank you.
2018-12-17 05:26 PM
Print stuff out so you know what the system thinks it's doing, no need to be guessing..
printf("Core=%d, %d MHz\n", SystemCoreClock, SystemCoreClock / 1000000);
printf("HCLK=%d\n", HAL_RCC_GetHCLKFreq());
printf("APB1=%d\n", HAL_RCC_GetPCLK1Freq());
printf("APB2=%d\n", HAL_RCC_GetPCLK2Freq());
If you have APB as DIV4 and AHB as DIV4, the APB Clock will be DIV16 won't it? And the TIMCLK as DIV8
The diagram is inelegant, I'll give you that..
2018-12-17 05:34 PM
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; // 200 MHz
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV4;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV4;
Core=50000000, 50 MHz
HCLK=50000000
APB1=12500000
APB2=12500000
2018-12-18 02:15 PM
My mistake, had a problem with the clocks, my AHB prescaler was set to 4 but so was the APB prescaler, giving me 10 MHz, therefore 20 MHz for the clocks, now it makes sense. Thanks!