Beginner STM32, feel the most egg pain is its clock system, every time see its clock tree is a bit dizzy, although read a lot of this information, even has written a lot of STM32 module code, did some small project, but always still on this piece of vague, indefinitely, So I want to write a little bit of my knowledge of it, step-by-step, until the day of full straightened out, (these things are not original, just want to help themselves understand)
In STM32, there are five clock sources for HSI, HSE, LSI, LSE, PLL.
HSI is a high-speed internal clock, an RC oscillator with a frequency of 8MHz.
The HSE is a high-speed external clock that can be connected to a quartz/ceramic resonator or to an external clock source with a frequency range of 4mhz~16mhz.
LSI is a low-speed internal clock, an RC oscillator with a frequency of 40kHz.
The LSE is a low-speed external clock with a quartz crystal with a frequency of 32.768kHz.
The PLL is a phase-locked loop multiplier output whose clock input source can be selected as HSI/2, HSE, or HSE/2. The multiplier can be selected as 2~16 times, but its output frequency must not exceed 72MHz (F103 maximum 72m,f20x maximum is 120m,f407 maximum of 168M).
Clock tree see Chinese reference manual;
Users can configure the frequency of the AHB bus, high speed APB2 bus, and low speed APB1 bus via multiple prescaler. The maximum frequency for the AHB and APB2 domains is 72MHZ. The maximum allowable frequency for the APB1 domain is 36MHZ. The clock frequency of the Sdio interface is fixed to HCLK/2.
The 40kHz LSI is used by independent watchdog IWDG, and it can also be selected as the clock source for real-time clock RTC. In addition, the clock source of the real-time clock RTC can also be selected LSE, or the 128 division of HSE. RTC's clock source is selected via rtcsel[1:0].
There is a full-speed USB module in the STM32, and its serial interface engine requires a clock source with a frequency of 48MHz. The clock source can only be obtained from the PLL output, optionally 1.5 or 1, that is, when a USB module is required, the PLL must be enabled, and the clock frequency is configured to 48MHz or 72MHz.
In addition, the STM32 can select a PLL output of 2, HSI, HSE, or the system clock SYSCLK output to the MCO foot (PA8). The system clock SYSCLK is a clock source for most parts of the STM32, which can be selected for PLL output, HSI, or HSE (PLL Octave to 72Mhz in general) before selecting the clock source, be careful to determine whether the target clock source is stable oscillation. Max=72mhz, it is divided into 2-way, 1-way to I2S2, I2s3 used I2S2CLK,I2S3CLK, the other 1 way through the AHB Divider Division (1/2/4/8/16/64/128/256/512) divided into the following 8 large modules use:
The ① is given to Sdio using the SDIOCLK clock.
The ② is given to FSMC using the FSMCCLK clock.
The ③ is sent to the AHB bus, kernel, memory, and DMA using the HCLK clock.
④ The system timer clock (SysTick) sent to Cortex by 8.
The ⑤ is sent directly to the cortex idle run clock fclk.
⑥ sent to APB1 divider. APB1 Divider can choose 1, 2, 4, 8, 16 divided, its output for APB1 peripheral use (PCLK1, the maximum frequency 36MHz), the other way to the timer (timer2-7) 2, 3, 4 times frequency multiplier used. The multiplier can choose 1 or twice times, the clock output for Timers 2, 3, 4, 5, 6, 7 use.
⑦ sent to APB2 divider. APB2 Divider can choose 1, 2, 4, 8, 16 divided, its output for APB2 peripheral use (PCLK2, the maximum frequency of 72MHz), and the other way to the timer (Timer1, Timer8) 1, twice frequency multiplier used. The multiplier can choose 1 or twice times, the clock output for the timer 1 and timer 8 use. In addition, the APB2 divider has one output for the ADC divider, and the ADCCLK clock is sent to the ADC module for use after dividing it. The ADC divider can be divided into 2, 4, 6, 8.
The ⑧2 is sent to the Sdio AHB interface for use (HCLK/2).
Enable control of the clock output
Many of the above clock outputs are band-enabled, such as AHB bus clocks, core clocks, various APB1 peripherals, APB2 peripherals, and so on. When a module needs to be used, the corresponding clock must be enabled first. Note that the timer multiplier, when the division of the APB is 1 o'clock, its multiplier value is 1, otherwise its multiplier value is 2.
The devices connected to the APB1 (low Speed peripherals) are: Power Interface, Backup interface, CAN, USB, i2c1, I2C2, UART2, UART3, SPI2, window watchdog, Timer2, Timer3, Timer4. Note that the USB module requires a separate 48MHz clock signal, but it should not be a clock for the USB module to work, but simply a clock to be used by the serial Interface Engine (SIE). The clock that the USB module works on should be provided by APB1.
The devices connected to the APB2 (high-speed peripherals) are: Gpio_a-e, USART1, ADC1, ADC2, ADC3, TIM1, TIM8, SPI1, AFIO;
Using the HSE clock, the program sets the clock parameter flow:
1, re-set the RCC register to the default value rcc_deinit;
2, open the external high-speed clock crystal HSE rcc_hseconfig (rcc_hse_on);
3, waiting for external high-speed clock crystal oscillator work Hsestartupstatus = Rcc_waitforhsestartup ();
4, set AHB clock rcc_hclkconfig;
5, set the high-speed AHB clock rcc_pclk2config;
6, set the low speed AHB clock rcc_pclk1config;
7, set the PLL rcc_pllconfig;
8. Turn on the PLL rcc_pllcmd (ENABLE);
9. Wait for the PLL to work while (Rcc_getflagstatus (rcc_flag_pllrdy) = = RESET)
10, set the system clock rcc_sysclkconfig;
11. Determine if the PLL is the system clock while (Rcc_getsysclksource ()! = 0x08)
12. Open the peripheral clock to be used Rcc_apb2periphclockcmd ()/rcc_apb1periphclockcmd ()
About the Systeminit function
Beginners are easy to confuse is that in our source code project, we did not go to manually set the system clock, many times did not go to the tube it, but we write the marquee, Gpio control, serial communication and other small programs can still run normally, this is why?
The fundamental reason is that the system itself has been set up for us, there is a default setting function (Systeminit ()), it is strange that we do not see it in the main function, because the system writes it in the boot file (startup_ XXX.S), and executed before the main function, so we do not see, such as:
About the STM32 clock system