cancel
Showing results for 
Search instead for 
Did you mean: 

How PLL affects timer Pre-sclaer.

DJ1
Associate III

Below i have attached a code which enables the PLL freq of 72MHz using HSI of 16MHz. The issue is if I give a Timer pre-scaler of 36000-1 (I am using timer2, which in case of STM32F401RE is on APB1 bus so using a pre-scaler of 2 for APB1 which makes it 36MHz, thus a pre-scaler of 36000-1 will generate a delay of 1 ms). Desired outcome is to generate 1 ms timer delay but it is not 1 ms when tested with timer ARR is set 5000. I have already checked clock using MCO1 pin with a pre-scaler of 2 which gave 36MHz on DSO. When  i call a delay function by passing 5000 as timer ARR value, then i hardly get 2500 - 3000 ms delay.

Below is my RCC_Init() function, please let me know is there any other settings are needed for setting up timers using PLL. 

void tim_init()
{
TIM2_EN;
//TIM2->TIMx_PSC = 36000-1;
TIM2->TIMx_PSC = 16000-1;
//TIM2->TIMx_PSC = 80000-1;
//TIM2->TIMx_PSC = 72000 - 1;
}
 
void delay(uint16_t x)
{
TIM2->TIMx_ARR = x;
TIM2->TIMx_CNT = 0;
TIM2->TIMx_CR1 |= (1 << 0);
while(TIM2->TIMx_CNT < x);
}
void RCC_Init()
{
/*
* RCC Settings for setting upto 80MHz freq using HSI based PLL
*/
 
// Set PLL clock for MCO output
//RCC->CFGR |= (3 << 21);
// Set pre-scaler for MCO1 bcoz of Logic Analyzer
//RCC->CFGR |= (4 << 24);
 
 
 
// Power Settings
// Enable Power Setting;
RCC->APB1ENR |= (1 << 28);
// Set VSO to 3
PWR->PWR_CR |= (2 << 14);
// dummy Read
uint8_t dummy = PWR->PWR_CR;
 
 
// Program number of wait states to the Latency bits in ACR
FLASH->FLASH_ACR |= (2 << 0);
// Read Flash ACR
uint8_t dummy1 = FLASH->FLASH_ACR;
// Enable Pre-fetch
FLASH->FLASH_ACR |= (1 << 8);
// Enable Data Cache
FLASH->FLASH_ACR |= (1 << 10);
// Enable Instruction Cache
FLASH->FLASH_ACR |= (1 << 9);
 
#ifdef HSE
 
// Turn ON HSE
RCC->CR |= (1 << 16);
// Wait till ready
while(!(RCC->CR >> 17 & 1));
// Set HSE as PLL source
RCC->CFGR |= (1 << 22);
// Turn OFF HSI
RCC->CR &= ~(1 << 0);
// Enable Clock security CSS
RCC->CR |= (1 << 19);
 
 
#else
 
// Turn on HSI ON
RCC->CR |= (1 << 0);
// wait until HSI is ready
while(!(RCC->CR >> 1 & 1));
 
#endif
 
 
// Clear the default 192 setting
RCC->PLLCFGR &= ~(192 << 6);
// Set 200 to PLLN
RCC->PLLCFGR |= (216 << 6);
// Clear the default 16 setting
RCC->PLLCFGR &= ~(16 << 0);
// Set 8 to PLLM
RCC->PLLCFGR |= (8 << 0);
// Set PLLP to 6
RCC->PLLCFGR |= (2 << 16);
// Clear PLLQ
RCC->PLLCFGR &= ~(4 << 24);
// Set PLLQ to 9
RCC->PLLCFGR |= (9 << 24);
 
// Set Pre-scaler 2 for APB1 bus within 42MHz
RCC->CFGR |= (4 << 10);
 
// Turn on PLL from RCC CR Register
RCC->CR |= (1 << 24);
// Wait till PLL is ready
while(!(RCC->CR >> 25 & 1));
 
// SET PLL as system clock
RCC->CFGR |= (2 << 0);
// Wait until PLL Switch Status is SET
while(!(RCC->CFGR >> 2 & 2));
}
12 REPLIES 12

Timer clocks are used only in the Timers. The APB peripheral clocks are used by all other peripherals on the APB bus, e.g. USART, SPI, I2C...

JW

Okay, so you are saying that the timer clock is still 72MHz, but due to timer PSC limitation of only 16 bits, hence the 36000-1, due to this reason we are doubling the ARR value. Is it? 

Also can you please once again explain about the role of TIMPRE bit in RCC_DCKCFGR.

> Okay, so you are saying that the timer clock is still 72MHz, but due to timer PSC limitation of only 16 bits, hence the 36000-1, due to this reason we are doubling the ARR value. Is it?

Yes.

> Also can you please once again explain about the role of TIMPRE bit in RCC_DCKCFGR.

It's an afterthought.

Original behaviour of TIM clocks in STM32 is, that if APB clock is undivided, TIM clock is equal to APB clock; if APB clock is divided by any ratio (i.e. /2, /4, /8, /16), TIM clock is twice the APB clock. In other words, if APB clock is AHB clock /1 or /2, TIM clock is equal to AHB clock; otherwise TIM clock uses the next higher output from the AHB divider than the APB clock uses.

That's the default behaviour also with TIMPRE (being 0 by default).

Later some users may have complained that with higher APB divider the timers are unnecessarily slow, so as an afterthough ST added TIMPRE, which if set to 1, TIM clock is equal to AHB clock both when APB divider is /1 and /2, and equal to APB*4 when APB divider is /4. In other words, TIM clock is directly the AHB clock when APB divider is /1 and /2, and then is derived from two higher tap of the divider chain than the APB clock.

JW