Stm32 RCC clock Analysis

Source: Internet
Author: User
Tags prefetch
The stm32 chip manual shows clearly that there are four clock sources:
1. HSI (Internal High-Speed clock 8 MHz) provides a clock source that supports BIT system clock
2. HSE (external high-speed clock) provides system clock and RTC clock source
3. LSE (low-speed external clock 32.768 kHz) can provide a clock source for rtc
4. LSI (low-speed internal clock) can provide the clock source for the independent watchdog


First, let's analyze the database function provided by ST: I use 3.5 of the database.


Let's see what is in systeminit.


Void systeminit (void)
{
RCC-> Cr | = (uint32_t) 0x00000001; // enable the HSI Internal High-Speed clock
# Ifndef stm32f10x_cl
RCC-> cfgr & = (uint32_t) 0xf8ff0000; // The 27-bit cfcg register is useless, so this macro is useless.
# Else // The two sides of the MCO are cleared, and the clock is not output out, 0-15 digits are cleared, Plck 2 is divided into ADC, and hclk is not divided into apb2.
RCC-> cfgr & = (uint32_t) 0xf0ff0000; // hclk is not divided into apb1, sysclk is not divided into AHB, and HSI is used as the system clock,
# Endif/* stm32f10x_cl */

/* Reset hseon, csson and pllon bits */
RCC-> Cr & = (uint32_t) 0xfef6ffff; // disable HSE


/* Reset hsebyp bit */
RCC-> Cr & = (uint32_t) 0 xfffbffff; // The External High-Speed clock is not bypassed.


/* Reset pllsrc, pllxtpre, pllmul and usbpre/otgfspre bits */
RCC-> cfgr & = (uint32_t) 0xff80ffff; // The PLL is divided into two groups: USB pre, pllmul * 2, and PLL input HSI/2.


# Ifdef stm32f10x_cl
/* Reset pll2on and pll3on bits */
RCC-> Cr & = (uint32_t) 0 xebffffff ;//


/* Disable all interrupts and clear pending bits */
RCC-> CIR = 0x00ff0000; // disable all interruptions and clear the interrupt flag.


/* Reset cfgr2 register */
RCC-> cfgr2 = 0x00000000;
# Elif defined (stm32f10x_ld_vl) | defined (stm32f10x_md_vl) | (defined stm32f10x_hd_vl)
/* Disable all interrupts and clear pending bits */
RCC-> CIR = 0x009f0000;


/* Reset cfgr2 register */
RCC-> cfgr2 = 0x00000000;
# Else
/* Disable all interrupts and clear pending bits */
RCC-> CIR = 0x009f0000;
# Endif/* stm32f10x_cl */

# If defined (stm32f10x_hd) | (defined stm32f10x_xl) | (defined stm32f10x_hd_vl)
# Ifdef data_in_extsram
Systeminit_extmemctl ();
# Endif/* data_in_extsram */
# Endif


/* Configure the system clock frequency, hclk, pclk2 and pclk1 prescalers */
/* Configure the flash latency cycles and enable prefetch buffer */
Setsysclock (); // finally call the clock setting function. The following analysis


# Ifdef vect_tab_sram
SCB-> vtor = sram_base | vect_tab_offset;/* the interrupt vector table is located at sram_base (0x20000000) + vect_tab_offset (0x0 */
# Else
SCB-> vtor = flash_base | vect_tab_offset;/* the interrupt vector table is located at flash_base (0x08000000) + vect_tab_offset (0x0 */
# Endif
}


Let's take a look at the setsysclock () function.


Static void setsysclock (void)
{
# 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
 
/* If no macro is set above, HSI is used as the system clock source. Generally, setsysclockto72 () function is called */
}


Static void setsysclockto72 (void)
{
_ IO uint32_t startupcounter = 0, hsestatus = 0; // _ IO uint32_t stands for vu32

/* Sysclk, hclk, pclk2 and pclk1 configuration ---------------------------*/
/* Enable HSE */
RCC-> Cr | = (uint32_t) rcc_cr_hseon); // rcc_cr_hseon (uint32_t) 0x00010000) HSE enabling
 
/* Wait till HSE is ready and if time out is reached exit */
Do
{
Hsestatus = RCC-> Cr & rcc_cr_hserdy; // rcc_cr_hserdy (uint32_t) 0x00020000) test HSE status
Startupcounter ++; // count wait
} While (hsestatus = 0) & (startupcounter! = Hsestartup_timeout); // when counting> hsestartup_timeout (0x500) and HSE is available, it jumps out.


If (RCC-> Cr & rcc_cr_hserdy )! = Reset) // If HSE is available
{
Hsestatus = (uint32_t) 0x01; // set hsestatus to 1
}
Else
{
Hsestatus = (uint32_t) 0x00; // set hsestatus to 0
}


If (hsestatus = (uint32_t) 0x01) // when HSE is available
{
/* Enable prefetch buffer */
Flash-> ACR | = flash_acr_prftbe;


/* Flash 2 wait state */
Flash-> ACR & = (uint32_t) (uint32_t )~ Flash_acr_latency );
Flash-> ACR | = (uint32_t) flash_acr_latency_2;


 
/* Hclk = sysclk */
RCC-> cfgr | = (uint32_t) rcc_cfgr_hpre_div1; // hclk equals to the system clock

/* Pclk2 = hclk */
RCC-> cfgr | = (uint32_t) rcc_cfgr_ppre2_div1; // APB pre-division is hclk

/* Pclk1 = hclk */
RCC-> cfgr | = (uint32_t) rcc_cfgr_ppre1_div2; // The pre-division of APB high and low speed is hclk/2


# Ifdef stm32f10x_cl
/* Configure plls ------------------------------------------------------ * // No pll2
/* Pll2 configuration: pll2clk = (HSE/5) * 8 = 40 MHz */
/* Prediv1 configuration: prediv1clk = pll2/5 = 8 MHz */

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_cfgr2_pll2mul8 |
Rcc_cfgr2_prediv1src_pll2 | rcc_cfgr2_prediv1_div3 );

/* Enable pll2 */
RCC-> Cr | = rcc_cr_pll2on;
/* Wait till pll2 is ready */
While (RCC-> Cr & rcc_cr_pll2rdy) = 0)
{
}


/* PLL configuration: pllclk = prediv1 * 9 = 72 MHz */
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
/* PLL configuration: pllclk = HSE * 9 = 72 MHz * // pl9's multiplier = 72 MHz
RCC-> cfgr & = (uint32_t) (uint32_t )~ (Rcc_cfgr_pllsrc | rcc_cfgr_pllxtpre |
Rcc_cfgr_pllmull ));
RCC-> cfgr | = (uint32_t) (rcc_cfgr_pllsrc_hse | rcc_cfgr_pllmula9 );
# Endif/* stm32f10x_cl */


/* Enable PLL */
RCC-> Cr | = rcc_cr_pllon; // enable PLL


/* Wait till PLL is ready */
While (RCC-> Cr & rcc_cr_pllrdy) = 0) // wait for the PLL to be ready
{
}

/* Select PLL as system clock source * // set the system clock as the PLL clock source
RCC-> cfgr & = (uint32_t) (uint32_t )~ (Rcc_cfgr_sw ));
RCC-> cfgr | = (uint32_t) rcc_cfgr_sw_pll;


/* Wait till PLL is used as system clock source * // wait for the system clock to be ready
While (RCC-> cfgr & (uint32_t) rcc_cfgr_sws )! = (Uint32_t) 0x08)
{
}
}
Else
{/* If HSE fails to start-up, the application will have wrong clock
Configuration. User can add here some code to deal with this error */


/* Go to infinite loop */
While (1) // If HSE cannot be used, jump into the endless loop
{
}
}
}



Stm32 RCC clock Analysis

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.