RCC
Last updated
Last updated
ecRCC.h
#ifndef __EC_RCC_H
#define __EC_RCC_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
//#include "stm32f411xe.h"
void RCC_HSI_init(void);
void RCC_PLL_init(void);
void RCC_GPIOA_enable(void);
void RCC_GPIOB_enable(void);
void RCC_GPIOC_enable(void);
// void RCC_GPIO_enable(GPIO_TypeDef * GPIOx);
extern int EC_SYSCL;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
``
ecRCC.c
#include "stm32f4xx.h"
#include "ecRCC.h"
volatile int EC_SYSCLK=16000000;
void RCC_HSI_init() {
// Enable High Speed Internal Clock (HSI = 16 MHz)
//RCC->CR |= ((uint32_t)RCC_CR_HSION);
RCC->CR |= 0x00000001U;
// wait until HSI is ready
//while ( (RCC->CR & (uint32_t) RCC_CR_HSIRDY) == 0 ) {;}
while ( (RCC->CR & 0x00000002U) == 0 ) {;}
// Select HSI as system clock source
RCC->CFGR &= (uint32_t)(~RCC_CFGR_SW); // not essential
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_HSI; //00: HSI16 oscillator used as system clock
// Wait till HSI is used as system clock source
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != 0 );
//EC_SYSTEM_CLK=16000000;
//EC_SYSCLK=16000000;
EC_SYSCLK=16000000;
}
void RCC_PLL_init() {
// To correctly read data from FLASH memory, the number of wait states (LATENCY)
// must be correctly programmed according to the frequency of the CPU clock
// (HCLK) and the supply voltage of the device.
FLASH->ACR &= ~FLASH_ACR_LATENCY;
FLASH->ACR |= FLASH_ACR_LATENCY_2WS;
// Enable the Internal High Speed oscillator (HSI)
RCC->CR |= RCC_CR_HSION;
while((RCC->CR & RCC_CR_HSIRDY) == 0);
// Disable PLL for configuration
RCC->CR &= ~RCC_CR_PLLON;
// Select clock source to PLL
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLSRC; // Set source for PLL: clear bits
RCC->PLLCFGR |= RCC_PLLCFGR_PLLSRC_HSI; // Set source for PLL: 0 =HSI, 1 = HSE
// Make PLL as 84 MHz
// f(VCO clock) = f(PLL clock input) * (PLLN / PLLM) = 16MHz * 84/8 = 168 MHz
// f(PLL_R) = f(VCO clock) / PLLP = 168MHz/2 = 84MHz
RCC->PLLCFGR = (RCC->PLLCFGR & ~RCC_PLLCFGR_PLLN) | 84U << 6;
RCC->PLLCFGR = (RCC->PLLCFGR & ~RCC_PLLCFGR_PLLM) | 8U ;
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLP; // 00: PLLP = 2, 01: PLLP = 4, 10: PLLP = 6, 11: PLLP = 8
// Enable PLL after configuration
RCC->CR |= RCC_CR_PLLON;
while((RCC->CR & RCC_CR_PLLRDY)>>25 != 0);
// Select PLL as system clock
RCC->CFGR &= ~RCC_CFGR_SW;
RCC->CFGR |= RCC_CFGR_SW_PLL;
// Wait until System Clock has been selected
while ((RCC->CFGR & RCC_CFGR_SWS) != 8UL);
// The maximum frequency of the AHB and APB2 is 100MHz,
// The maximum frequency of the APB1 is 50 MHz.
RCC->CFGR &= ~RCC_CFGR_HPRE; // AHB prescaler = 1; SYSCLK not divided (84MHz)
RCC->CFGR &= ~RCC_CFGR_PPRE1; // APB high-speed prescaler (APB1) = 2, HCLK divided by 2 (42MHz)
RCC->CFGR |= RCC_CFGR_PPRE1_2;
RCC->CFGR &= ~RCC_CFGR_PPRE2; // APB high-speed prescaler (APB2) = 1, HCLK not divided (84MHz)
EC_SYSCLK=84000000;
}