Reputation: 62
It's been days which I'm reading the reference manual and changing the code to configure the STM32F401RE timers clock. It seems that SYSCLK is set at 84MHZ, PCLK1 is 42MHZ, and PCLK2 is 84MHZ. but every time I want to use TIM2, the clock is set at 1.6MHZ. I used my phone and lap the time from led on and led off states and with the PSC and ARR I assumed that clock frequency is something around 1.6MHZ
here is clock configuration
RCC->APB1ENR |= RCC_APB1ENR_PWREN;
PWR->CR &= ~PWR_CR_VOS_Msk;
PWR->CR |= PWR_CR_VOS_1; // scale mode 2
// flash
FLASH->ACR &= ~FLASH_ACR_LATENCY;
FLASH->ACR |= FLASH_ACR_LATENCY_2WS;
// HSI CONFIGURATION
RCC->CR |= RCC_CR_HSION;
while( !(RCC->CR & RCC_CR_HSIRDY) ){}
// PLL CONFIGURATION
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLSRC; // PLL SRC= HSI
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLM_Msk;
RCC->PLLCFGR |= 16 << RCC_PLLCFGR_PLLM_Pos;
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLN_Msk;
RCC->PLLCFGR |= 336 << RCC_PLLCFGR_PLLN_Pos;
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLP_Msk;
RCC->PLLCFGR |= RCC_PLLCFGR_PLLP_0; // div4
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLQ_Msk;
RCC->PLLCFGR |= 4 << RCC_PLLCFGR_PLLQ_Pos;
RCC->CR |= RCC_CR_PLLON;
while( !(RCC->CR & RCC_CR_PLLRDY) ){}
// CPU, AHB, APB buses clocks
RCC->CFGR &= ~RCC_CFGR_SW_Msk;// PLL CLK SRC
RCC->CFGR |= RCC_CFGR_SW_PLL;
while( !(RCC->CFGR & RCC_CFGR_SWS_PLL) ){}
// flash
FLASH->ACR &= ~FLASH_ACR_LATENCY;
FLASH->ACR |= FLASH_ACR_LATENCY_2WS;
RCC->CFGR &= ~RCC_CFGR_HPRE; // AHB DIV 1
RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
RCC->CFGR &= ~RCC_CFGR_PPRE1_Msk; // APB1 DIV 2
RCC->CFGR |= RCC_CFGR_PPRE1_DIV2;
RCC->CFGR &= ~RCC_CFGR_PPRE2_Msk; // APB2 DIV 1
RCC->CFGR |= RCC_CFGR_PPRE2_DIV1;
SystemCoreClockUpdate();
and here is the timer2 configuration
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
TIM2->CR1 |= TIM_CR1_CKD_1;
TIM2->PSC = 1093-1;
TIM2->ARR = 1024 - 1;
TIM2->CNT = 0;
TIM2->DIER |= TIM_DIER_UIE;
NVIC_EnableIRQ(TIM2_IRQn);
TIM2->CR1 |= TIM_CR1_CEN;
Is there anything I missed or misunderstood in the configuration?
Upvotes: 1
Views: 1876
Reputation: 2592
Your code seems mostly correct. There are 2 problems I can detect, but I'm not sure if they are the real causes.
I'm not sure if there are other errors, but I have tested the code below on a F4 Discovery board. It has a STM32F407, but this uC is quite similar to yours.
FLASH->ACR |= FLASH_ACR_LATENCY_2WS; // 2 wait state for 84 MHz
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLQ;
RCC->PLLCFGR |= (7 << RCC_PLLCFGR_PLLQ_Pos); // PLL-Q: /7
RCC->PLLCFGR |= RCC_PLLCFGR_PLLSRC_HSI; // PLL source is HSI
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLP;
RCC->PLLCFGR |= (0b01 << RCC_PLLCFGR_PLLP_Pos); // PLL-P: /4
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLN;
RCC->PLLCFGR |= (336 << RCC_PLLCFGR_PLLN_Pos); // PLL-N: x336
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLM;
RCC->PLLCFGR |= (16 << RCC_PLLCFGR_PLLM_Pos); // PLL-M: /16
RCC->CR |= RCC_CR_PLLON; // Activate the PLL (Output: 84 MHz)
while ((RCC->CR & RCC_CR_PLLRDY) == 0); // Wait until PLL is ready
RCC->CFGR |= RCC_CFGR_HPRE_DIV1 // AHB divider: /1 (84 MHz)
| RCC_CFGR_PPRE1_DIV2 // APB1 divider: /2 (42 MHz)
| RCC_CFGR_PPRE2_DIV1; // APB2 divider: /1 (84 MHz)
RCC->CFGR |= RCC_CFGR_SW_PLL; // Switching to PLL clock source
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL); // Wait until switching is complete
And this is how I configured TIM2 to trigger interrupts with 1 Hz frequency
TIM2->PSC = 42000 - 1;
TIM2->ARR = 2000 - 1; // 1 sec. overflow time @ 84 MHz
TIM2->EGR |= TIM_EGR_UG; // Event generation to update prescaler
TIM2->DIER |= TIM_DIER_UIE; // Enable update interrupt in peripheral
TIM2->CR1 |= TIM_CR1_CEN; // Start timer
NVIC_EnableIRQ(TIM2_IRQn); // Enable interrupt in NVIC
Upvotes: 2