Detailed explanation of RCC examples
#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL) //If these system clocks are defined, they will be set to 24M. If not defined, they will be 72M
#define SYSCLK_FREQ_24MHz 24000000
#else
#define SYSCLK_FREQ_72MHz 72000000 //Definition of the default value of the system clock. If the external high-speed clock is not defined, the internal high-speed clock is used, which is 8000000
#endif
#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL) //Internal and external SRAM selection
#endif
#define VECT_TAB_OFFSET 0x0
#ifdef SYSCLK_FREQ_HSE
uint32_t SystemCoreClock = SYSCLK_FREQ_HSE;
#elif defined SYSCLK_FREQ_24MHz
uint32_t SystemCoreClock = SYSCLK_FREQ_24MHz;
#elif defined SYSCLK_FREQ_36MHz
uint32_t SystemCoreClock = SYSCLK_FREQ_36MHz;
#elif defined SYSCLK_FREQ_48MHz
uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz;
#elif defined SYSCLK_FREQ_56MHz
uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz;
#elif defined SYSCLK_FREQ_72MHz
uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz;
#else
uint32_t SystemCoreClock = HSI_VALUE;
#endif
__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; //AHB recipe table
static void SetSysClock(void); //Function declaration for setting the system clock
//The following is the declaration of the corresponding functions used according to the definitions of different system clocks, in preparation for the subsequent function calls
#ifdef SYSCLK_FREQ_HSE
static void SetSysClockToHSE(void);
#elif defined SYSCLK_FREQ_24MHz
static void SetSysClockTo24(void);
#elif defined SYSCLK_FREQ_36MHz
static void SetSysClockTo36(void);
#elif defined SYSCLK_FREQ_48MHz
static void SetSysClockTo48(void);
#elif defined SYSCLK_FREQ_56MHz
static void SetSysClockTo56(void);
#elif defined SYSCLK_FREQ_72MHz
static void SetSysClockTo72(void);
#endif
#ifdef DATA_IN_ExtSRAM // Initialization function declaration after external SRAM selection
static void SystemInit_ExtMemCtl(void);
#endif
void SystemInit (void) //System initialization function, set the system clock and clock interrupt (called in startup_stm32f10x_md.s) (reset RCC clock configuration to default state until the clock function is set)
{
RCC->CR |= (uint32_t)0x00000001; //Internal high-speed clock enable, internal 8MHz clock turned on
#ifndef STM32F10X_CL
RCC->CFGR &= (uint32_t)0xF8FF0000; //MCO microcontroller has no clock output (for external pins), ADC pre-divided PCLK2 is used as ADC clock after 2 division, APB pre-divided HCLK is not divided, AHB pre-divided SYSCLK is not divided, HSI is used as system clock
//HSI is output as system clock (output), SYSCLK=PCLK=PCLK1=PCLK2=8M, ADCCLK=1/2(PCLK2)=4M
#else
RCC->CFGR &= (uint32_t)0xF0FF0000; //Same as above; bit 27 of RCC->CFGR is reserved and is always 0, HSI is output as system clock (not output because it is not compiled)
#endif
RCC->CR &= (uint32_t)0xFEF6FFFF; //Clock monitor off, HSE oscillator off
RCC->CR &= (uint32_t)0xFFFBFFFF; //External 4-25MHz oscillator is not bypassed
RCC->CFGR &= (uint32_t)0xFF80FFFF; //PLL clock is divided by 1.5 times as USB clock, PLL is output by 2 times, HSE is not divided, HSI clock is divided by 2 as PLL input clock
//PLLCLK=HSICLK=8M (not output yet), HSECLK=HSEOSC, USBCLK=PLLCLK/1.5, except for PLL, other division coefficients are 0
#ifdef STM32F10X_CL
RCC->CR &= (uint32_t)0xEBFFFFFF; //26 and 28 in CR are set to 0
RCC->CIR = 0x00FF0000; // Clear interrupt flags and disable some interrupts
RCC->CFGR2 = 0x00000000; //No such register
#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
RCC->CIR = 0x009F0000; //Clear interrupt flags, turn off some interrupts
RCC->CFGR2 = 0x00000000; //No such register
#else
RCC->CIR = 0x009F0000; //Clear interrupt flags and turn off some interrupts
#endif
#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
#ifdef DATA_IN_ExtSRAM
SystemInit_ExtMemCtl();//If the macro defines external SRAM, initialize it
#endif
#endif
SetSysClock(); //Set the system clock
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET;
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;
#endif
}
void SystemCoreClockUpdate (void)
{
uint32_t tmp = 0, pllmull = 0, pllsource = 0;
#ifdef STM32F10X_CL
uint32_t prediv1source = 0, prediv1factor = 0, prediv2factor = 0, pll2mull = 0;
#endif
#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
uint32_t prediv1factor = 0;
#endif
tmp = RCC->CFGR & RCC_CFGR_SWS;
switch (tmp)
{
case 0x00:
SystemCoreClock = HSI_VALUE;
break;
case 0x04:
SystemCoreClock = HSE_VALUE;
break;
case 0x08:
pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
#ifndef STM32F10X_CL
pllmull = ( pllmull >> 18) + 2;
if (pllsource == 0x00)
{
SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
}
else
{
#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1;
SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
#else
if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t)RESET)
{
SystemCoreClock = (HSE_VALUE >> 1) * pllmull;
}
else
{
SystemCoreClock = HSE_VALUE * pllmull;
}
#endif
}
#else
pllmull = pllmull >> 18;
if (pllmull != 0x0D)
{
pllmull += 2;
}
else
{
pllmull = 13 / 2;
}
if (pllsource == 0x00)
{
SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
}
else
{
prediv1source = RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC;
prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1;
if (prediv1source == 0)
{
SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
}
else
{
prediv2factor = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> 4) + 1;
pll2mull = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> 8 ) + 2;
SystemCoreClock = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull;
}
}
#endif
break;
default:
SystemCoreClock = HSI_VALUE;
break;
}
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
SystemCoreClock >>= tmp;
}
static void SetSysClock(void)//Set different system clocks according to different macro definitions
{
#ifdef SYSCLK_FREQ_HSE
SetSysClockToHSE();
#elif defined SYSCLK_FREQ_24MHz
SetSysClockTo24();
#elif defined SYSCLK_FREQ_36MHz
SetSysClockTo36();
#elif defined SYSCLK_FREQ_48MHz
SetSysClockTo48();
#elif defined SYSCLK_FREQ_56MHz
SetSysClockTo56();
#elif defined SYSCLK_FREQ_72MHz
SetSysClockTo72();
#endif
}
#ifdef DATA_IN_ExtSRAM
void SystemInit_ExtMemCtl(void)
{
RCC->AHBENR = 0x00000114;
RCC->APB2ENR = 0x000001E0;
GPIOD->CRL = 0x44BB44BB;
GPIOD->CRH = 0xBBBBBBBB;
GPIOE->CRL = 0xB44444BB;
GPIOE->CRH = 0xBBBBBBBB;
GPIOF->CRL = 0x44BBBBBB;
GPIOF->CRH = 0xBBBB4444;
GPIOG->CRL = 0x44BBBBBB;
GPIOG->CRH = 0x44444B44;
FSMC_Bank1->BTCR[4] = 0x00001011;
FSMC_Bank1->BTCR[5] = 0x00000200;
}
#endif
#ifdef SYSCLK_FREQ_HSE
static void SetSysClockToHSE(void)
{
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
RCC->CR |= ((uint32_t)RCC_CR_HSEON);
do
{
HSEStatus = RCC->CR & RCC_CR_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
if ((RCC->CR & RCC_CR_HSERDY) != RESET)
{
HSEStatus = (uint32_t)0x01;
}
else
{
HSEStatus = (uint32_t)0x00;
}
if (HSEStatus == (uint32_t)0x01)
{
#if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL && !defined STM32F10X_HD_VL
FLASH->ACR |= FLASH_ACR_PRFTBE;
FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
#ifndef STM32F10X_CL
FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_0;
#else
if (HSE_VALUE <= 24000000)
{
FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_0;
}
else
{
FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_1;
}
#endif
#endif
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1;
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_HSE;
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x04)
{
}
}
else
{
}
}
#elif defined SYSCLK_FREQ_24MHz
static void SetSysClockTo72(void) //Set the system clock to 72M: SYSCLK=72M, HCLK=72M, PCLK1=36M (up to 36M), PCLK2=72M, ADCCLK=36M,
{
__IO uint32_t StartUpCounter = 0, HSEStatus = 0; //Start counting, HSE status
RCC->CR |= ((uint32_t)RCC_CR_HSEON); //HSE enable
do //Loop until HSE is enabled successfully or times out
{
HSEStatus = RCC->CR & RCC_CR_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
if ((RCC->CR & RCC_CR_HSERDY) != RESET)
{
HSEStatus = (uint32_t)0x01; //HSE enabled successfully
}
else
{
HSEStatus = (uint32_t)0x00; //HSE enabled unsuccessfully
}
if (HSEStatus == (uint32_t)0x01) //HSE enabled successfully
{
FLASH->ACR |= FLASH_ACR_PRFTBE; //flash cache enabled
FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);//
FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;//
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; //RCC_CFGR_HPRE_DIV1=0, the value in CFGR remains unchanged
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; //RCC_CFGR_PPRE2_DIV1=0, the value in CFGR remains unchanged
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; //Low-speed APB pre-division divides HCLK by 2, APB1CLK=HCLK/2
#ifdef STM32F10X_CL
RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |
RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR 2_PLL2MUL8 | RCC_CFGR2_PREDIV1SRC_PLL2
| RCC_CFGR2_PREDIV1_DIV5);
RCC->CR |= RCC_CR_PLL2ON;
while((RCC->CR & RCC_CR_PLL2RDY) == 0)
{
}
RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 |
RCC_CFGR_PLLMULL9);
#else
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | //PLL input clock source HSI clock 2 After frequency division, it is used as PLL input clock, and HSE divider is used as PLL input clock. HSE does not divide
RCC_CFGR_PLLMULL)); //PLL frequency multiplication coefficient PLL 2 times frequency output (in order to clear other bits)
RCC->CFGR |= (uint32_t) (RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9); //PLL input clock source HSE clock as PLL input clock, PLL frequency multiplication factor PLL 9 times frequency output
#endif
RCC->CR |= RCC_CR_PLLON; //PLL enable
while((RCC->CR & RCC_CR_PLLRDY) == 0)//Wait for PLL to be enabled successfully
{
}
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));//HSI as system clock (to clear other bits)
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; //PLL output as system clock
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) //Wait until PLL is successfully used as system clock source
{
}
}
else
{
}
}
#endif
Previous article:Detailed explanation of STM32 clock RCC (Part 3)
Next article:Detailed explanation of STM32 clock RCC (Part 2)
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- Sandia Labs develops battery failure early warning technology to detect battery failures faster
- Ranking of installed capacity of smart driving suppliers from January to September 2024: Rise of independent manufacturers and strong growth of LiDAR market
- Industry first! Xiaopeng announces P7 car chip crowdfunding is completed: upgraded to Snapdragon 8295, fluency doubled
- P22-009_Butterfly E3106 Cord Board Solution
- Keysight Technologies Helps Samsung Electronics Successfully Validate FiRa® 2.0 Safe Distance Measurement Test Case
- Innovation is not limited to Meizhi, Welling will appear at the 2024 China Home Appliance Technology Conference
- Innovation is not limited to Meizhi, Welling will appear at the 2024 China Home Appliance Technology Conference
- Huawei's Strategic Department Director Gai Gang: The cumulative installed base of open source Euler operating system exceeds 10 million sets
- Microwave Solid-State Circuit Design (Second Edition)
- Let's take a look at the electromagnetic waves in Korean
- How terrible is it that an electric motorcycle battery explodes?
- Is there any official routine for developing EFM8 in Simplicity Studio? Where can I download it?
- What is the difference between W(b) and b in assembly language?
- 【Silicon Labs BG22-EK4108A Bluetooth Development Evaluation】+Power-on and Example Program Test
- "Power amplifier experimental case" application of power amplifier in forward and reverse motion of ultrasonic motor
- Share: [Zhongke Blue News] AB32VG1 Review SDIO (File System)
- Design of audio products based on DSP
- 【Chuanglong Technology Allwinner A40i Development Board】Performance Comprehensive Test