Practical information | For beginners: STM32 clock tree analysis
For readers who are new to STM32 (or even ARM devices), after becoming familiar with the development environment, they often "fall" on the same problem. The key word in this problem is: clock tree.
As we all know, the operation of microcontrollers (processors) must rely on periodic clock pulses to drive - often starting with an external crystal oscillator to provide clock input, and finally converted to the periodic operation of multiple external devices. The path of this clock "energy" diffusion flow is like the nutrients of a big tree flowing from the trunk to each branch, so it is often called a "clock tree". In some traditional low-end 8-bit microcontrollers such as 51, AVR, PIC and other microcontrollers, they also have their own clock tree system, but most of them are not controlled by users, that is, after the microcontroller is powered on, the clock tree is fixed in a certain unchangeable state (assuming that the microcontroller is in normal working state). For example, the 51 microcontroller uses a typical 12MHz crystal oscillator as the clock source, then the driving clock rate of peripherals such as IO ports, timers, serial ports and other devices is already fixed, and users cannot change this clock rate unless the crystal oscillator is replaced.
The clock tree of the STM32 microcontroller is configurable, and the clock input source and the clock rate that ultimately reaches the peripheral are no longer fixed. This article will analyze the clock tree of the STM32 microcontroller in detail. Figure 1 is the clock tree of the STM32 microcontroller, and Table 1 shows the components represented by the various numbers in the figure.
Figure 1 Explanation of symbols
1 Internal low speed oscillator (LSI, 40Khz)
2 External low speed oscillator (LSE, 32.768Khz)
3 External high speed oscillator (HSE, 3-25MHz)
4 Internal high speed oscillator (HIS, 8MHz)
5 PLL input selection bit
6 RTC clock selection bit
7 PLL1 frequency division register
8 PLL1 frequency multiplication register
9 System clock selection bit
10 USB frequency division register
11 AHB frequency division register
12 APB1 frequency division register
13 AHB bus
14 APB1 peripheral bus
15 APB2 frequency division register
16 APB2 peripheral bus
17 ADC prescaler register
18 ADC peripherals
19 PLL2 frequency division register
20 PLL2 frequency multiplication register
21 PLL clock source selection register
22 Independent watchdog devices
23 RTC devices
Figure 1 STM32 clock tree
Before understanding this clock tree, we must first clarify the "trunk" and the final "branch". Assuming that an external 8MHz crystal oscillator is used as the clock input source of the STM32 (which is also the most common practice), the 8MHz is the "trunk", and the "branch" is obviously the final external device such as the general-purpose input and output device (GPIO).
This makes it easy to find the "thread" of the first clock:
3——5——7——21——8——9——11——13
The following analysis is performed on this clock path:
For 3, first is the external 3-25MHz (previously assumed to be 8MHz) input;
For 5, the input clock of the subsequent PLL branch is pre-selected by the PLL selection bit (assuming an external crystal oscillator is selected);
For 7, set the frequency division of the external crystal oscillator (assuming 1 division);
For 21, select the clock source of the PLL frequency multiplication (assuming that the external crystal oscillator clock after frequency division is selected);
For 8, set the PLL multiplier (assuming 9 times);
For 9, select the system clock source (assuming that the clock output after PLL multiplication is selected);
For 11, set the AHB bus frequency division number (assuming 1 division);
For 13, the clock arrives at the AHB bus;
The GPIO peripherals introduced in the previous chapter belong to APB2 devices, that is, the GPIO clock comes from the APB2 bus. The clock trace of the GPIO peripherals can also be found in Figure 1:
3——5——7——21——8——9——11——15——16
For 3, first is the external 3-25MHz (previously assumed to be 8MHz) input;
For 5, the input clock of the subsequent PLL branch is pre-selected by the PLL selection bit (assuming an external crystal oscillator is selected);
For 7, set the frequency division of the external crystal oscillator (assuming 1 division);
For 21, select the clock source of the PLL frequency multiplication (assuming that the external crystal oscillator clock after frequency division is selected);
For 8, set the PLL multiplier (assuming 9 times);
For 9, select the system clock source (assuming that the clock output after PLL multiplication is selected);
For 11, set the AHB bus frequency division number (assuming 1 division);
For 15, set the APB2 bus frequency division number (assuming 1 division);
For 16, the clock arrives at the APB2 bus;
Now let's calculate the maximum drive clock rate of the GPIO device (all conditions have been assumed in the above points):
1) From 3, we know that the crystal input is 8MHz. From 5-21, we know that the clock source of the PLL is the external crystal clock after division, and the division number is 1. Therefore, we first conclude that the clock source of the PLL is: 8MHz / 1 = 8MHz.
2) From 8 and 9, we know that the PLL multiplication factor is 9, and the clock output after PLL multiplication is selected as the system clock, then the system clock is 8MHz * 9 = 72MHz.
3) The clock reaches the AHB prescaler. From 11, we know that the clock rate is still 72MHz after passing through the AHB prescaler.
4) The clock reaches the APB2 prescaler, and after passing through the APB2 prescaler, the rate is still 72MHz.
5) The clock arrives at the APB2 bus peripheral.
Therefore, the maximum speed that the APB2 bus peripheral of STM32 can reach is 72MHz. Based on the above method, readers can search for the origins of peripheral clocks such as APB1 bus peripheral clock, RTC peripheral clock, independent watchdog, etc. Next, analyze the setting of clock tree from the perspective of program. The program list is as follows:
void RCC_Configuration(void)
{
ErrorStatus HSEStartUpStatus; (1)
RCC_DeInit(); (2)
RCC_HSEConfig(RCC_HSE_ON); (3)
HSEStartUpStatus = RCC_WaitForHSEStartUp(); (4)
if(HSESTartUpStatus == SUCCESS) (5)
{
RCC_HCLKConfig(RCC_SYSCLK_Div1); (6)
RCC_PCLK2Config(RCC_HCLK_Div1); (7)
RCC_PCLK1Config(RCC_HCLK_Div2); (8)
FLASH_SetLatency(FLASH_Latency_2); (9)
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); (10)
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); (11)
RCC_PLLCmd(ENABLE); (12)
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); (13)
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); (14)
while(RCC_GetSYSCLKSource() != 0x08); (15)
}
}
The above is the STM32 clock tree configuration function provided by ST. Readers must first know 3 points
1. The library functions provided by ST have very good standardization and readability in function and variable naming (although a bit lengthy). Even without comments, you can roughly judge the meaning of the function or variable from the function name and variable name.
2. Secondly, the reader should distinguish the various buses and corresponding clocks from the above figure: PLLCLK represents the output clock of the PLL phase-locked loop, SYSCLK represents the system clock, HCLK represents the clock of the AHB bus, PCLK1 represents the clock of the APB1 bus, and PCLK2 represents the clock of the APB2 bus.
The purpose of the two codes 3, 9, and 10 is to set the waiting cycle of the internal FLASH of STM32. The explanation is as follows: the internal user FLASH of STM32 is used to store code instructions for CPU access and execution. The maximum speed of STM32 CPU is known to be 72MHz, but FLASH cannot reach such a high speed. Therefore, the so-called "waiting cycle" must be inserted in the process of CPU accessing FLASH. Obviously, the faster the CPU speed, the more waiting cycles need to be inserted. The principle is
1) When the CPU speed is 0 ~ 24MHz, there is no need to insert a waiting cycle, that is, wait until the number of cycles is 0;
2) When the CPU speed is 24 ~ 48MHz, insert 1 waiting cycle;
3) When the CPU speed is 48MHz ~ 72MHz, insert 2 waiting cycles;
After the above three preparations, start parsing this program:
(1) Define a variable HSEStartUpStatus of ErrorStatus type;
(2) Reset the clock tree to the default settings;
(3) Turn on the HSE crystal oscillator;
(4) Wait for the HSE crystal oscillator to start and stabilize, and save the start-up result to the HSEStartUpStatus variable;
(5) Determine whether the HSE crystal oscillator starts successfully (assuming it succeeds, enter the if function);
(6) Set the HCLK clock to 1 divided by SYSCLK;
(7) Set the PLCK2 clock to 1 divided by SYSCLK;
(8) Set the PLCK1 clock to 2 divided by SYSCLK;
(11) Select the PLL input source as the HSE clock divided by 1 and multiplied by 9;
(12) Enable the PLL output;
(13) Wait for the PLL output to stabilize;
(14) Select the system clock source as the PLL output;
(15) Wait for the system clock to stabilize;
The configuration order of the clock tree in the above code is (corresponding to the number in the figure):
3——11——14——15——7——21——8——9.
By comparison, it is found that the configuration order of the clock tree in the program is not configured from left to right and from top to bottom in the figure. Why is this? In fact, I believe that most readers can explain this problem by themselves: the thinking and operation methods in the electronic design world are often different from those in daily life. For example, people often connect the power supply to the TV first, and then turn on the TV switch; first open the main valve of the large water pipe, and then open the small faucet; in short, it is a sequence from "primary" to "secondary". Transferring to the most common 51 single-chip microcomputer development platform, developers often configure the timer's frequency division number, reload value and other parameters first, and then start the timer counting; first turn on the interrupts of each peripheral, and finally turn on the total interrupt; this is actually the opposite of people's living habits, a sequence of "secondary" first and "primary".
At this point, it is easy to understand the STM32 clock tree.
Recommended Reading
Practical | FreeRTOS study notes - application scenarios
Useful information | DIY an ARM learning machine
Practical | Application of enumeration variables and macros
Useful Information | Create a beautiful VFD voice clock
Useful information | Teach you how to make a mini mobile power bank with LED emergency light
Useful Information | Miscellaneous Talks on Voltage Stabilization
Useful information | Making your own PCB circuit board with an engraving machine
Useful Information | How to Use Digital Rotary Coding Switches