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