STM32 Programming. Part 3: Clocking System
Posted: 14 Oct 2023, 05:07
The first thing to deal with before further study of STM32 microcontrollers is the clocking and reset control system, called RCC. In this article we will look at how to properly configure the microcontroller to operate from an external 8 MHz quartz resonator.
The clocking system in STM32 compared to AVR microcontrollers is quite intricate. Let's understand it.
Contents:
In STM32 microcontrollers, all peripherals (I/O ports, timers, SPI interfaces, etc.) are connected to so-called buses, through which the peripherals receive clock signals and communicate with the bus master (e.g., the processor).
There are three main buses in the STM32F103x8: AHB, APB1 and APB2. Each bus has a certain group of devices hanging on it:
AHB: CPU core, memory, and DMA;
APB1: USART2, USART3, I2C1/2, CAN, timers TIM2..4;
APB2: GPIO ports, ADC, USART1, TIM1, SPI1.
In the datasheet for the STM32F103x8 there is a block diagram that shows which peripherals are connected where:
The diagram in Fig. 1 may seem complicated and incomprehensible at first, this is normal, in time everything will settle in your head and the feeling of incomprehension will disappear.
There is also this table, which also shows the peripheral devices and the buses to which they are connected:
It can be seen that in Fig. 2 the bus name (AHB, APB1 and APB2) has its maximum frequency in parentheses. Since the peripheral devices receive the clock signal from the bus, its frequency sets the speed of the devices connected to this bus. Below we will consider how to set the frequency of each of the microcontroller buses.
Another feature of the STM32 clocking system is that after the reset signal of the microcontroller all peripherals are in a disabled state and no clock signal is supplied to them. This is done in order to reduce power consumption of the entire microcontroller. Before you start working with any peripheral device, you must enable the clock signal to it. How to do this will be discussed below.
So, here are the main points to remember:
Several clock generators are present in the STM32F103x8/B microcontrollers:
The first of these is an 8 MHz internal RC oscillator called the High-speed internal (HSI) RC oscillator. After reset, the microcontroller is clocked from this oscillator by default. Its main advantage is that no additional external components are needed for the oscillator to work. However, its disadvantage is poor stability of the generated frequency: when the ambient temperature changes, its frequency of 8 MHz will float a bit. This may not be critical for devices not demanding time intervals, but in some cases this feature is unacceptable.
Next is the High-speed external (HSE). This oscillator is an alternative to HSI. It requires an external quartz resonator for 4-16 MHz. Its main advantage in comparison with HSI is the stability of the generated frequency. Also, with some customization, the OSC_IN pin can be connected to a source of a ready rectangular clock signal without using a resonator.
Next is the Low-speed external (LSE). This oscillator also requires an external quartz resonator, but only at 32768 Hz. The LSE is only used to clock the built-in RTC real-time clock, which can be used to clock the current time if needed.
The last oscillator is the low-speed internal (LSI) RC oscillator. This is a 40 kHz internal RC oscillator. It is not very accurate, but it has a very important task: generating a clock signal for the MC watchdog timer, which will restart the system in case of a hang-up. You can also clock the RTC from LSI, but most likely nobody will do this.
Peripheral clocking
The processor core and most peripherals use the SYSCLK clock signal.
After the AHB Prescaler, the clock signal is distributed among the microcontroller buses. The HCLK signal goes to the processor core, memory and the AHB bus periphery. FCLK also goes to the core. The clocking is fed to the Cortex System timer via a fixed divider by 8. The APB1 Prescaler generates the clocking signal for APB1 bus devices and the APB2 Prescaler for APB2 devices.
There is a small peculiarity of clock signal generation for timers and ADCs. The clock signal is applied to the timers as follows. If the bus divider (APB1 Prescaler or APB2 Prescaler) is set to one, the clocking frequency of the timers (TIMXCLK or TIM1CLK) will be equal to the bus frequency. But, if the divider is not equal to one, then the clocking frequency of the timers will be 2 times the bus frequency (see Figure 5, 6). This is how the ADC has its own divider, which forms the ADCCLK signal from the APB2 bus clock frequency (Fig. 6).
I think we should also pay attention to these elements of the block diagram:
These are nothing but devices for supplying a clock signal to a specific peripheral (2I logic elements). I will try to redraw one of them to make it clearer what it is and how it works:
Each peripheral module has its own bit in a special register (SPI1EN, IOPAEN, IOABEN and so on), which, when set to one, allows the clock signal to be applied to it. In Fig. 8 I have given an example only for the clock signal PCLK2 of the APB2 bus, for the other signals (HCLK, PCLK1, TIMXCLK, TIM1CLK) it is the same.
SYSCLK signal sources
So now we know that the main clock signal in STM32 microcontrollers is SYSCLK. Let's now understand how to get it. We have 3 options at our disposal: HSI, HSE and PLL generators:
After resetting the microcontroller, the built-in RC generator HSI is set as the default source of the SYSCLK signal. The clock signal flow for this case is shown in Fig. 10, the default values of all dividers are circled:
Now let's calculate the values of all frequencies in the default configuration. The frequencies of HCLK, FCLK, PCLK1, TIMXCLK, PCLK2, TIM1CLK will be equal to 8 MHz, the frequency of Cortex System timer is equal to 1 MHz, and ADCCLK is 4 MHz.
If we want to use the HSE generator, the picture is as follows:
When using an 8 MHz quartz resonator, all system frequencies will be the same as in the previous case. The only difference is that the frequency stability is better when using the HSE oscillator than when using HSI. However, if we want to maximize the performance of the whole system, we need to use a PLL frequency multiplier block as the SYSCLK source.
HSE and PLL
In STM32 microcontrollers, the PLL module can be clocked either from the HSI oscillator or from the HSE. There are a huge number of options for configuring the system clocking from the PLL. We will focus on only one, in which HSE is used and all coefficients are set to maximize system performance:
The quartz resonator is selected for 8 MHz. Next, the signal from the HSE without division (set by the PLLXTPRE bit) is fed to the PLLSRC selector and then to the PLL. In order to get 72 MHz from 8 MHz, the PLL multiplication factor must be PLLMUL=9. Next, the signal from the 72 MHz PLL goes to SYSCLK through the SW selector. Since we want to clock the processor core at a maximum frequency of 72 MHz, we set the AHB Prescaler equal to one (no division). To get the APB1 bus frequency equal to 36 MHz, we set APB1 Prescaler equal to 2. The APB2 bus has a maximum frequency of 72 MHz, so the APB2 Prescaler can be set to 1.
Total:
HSE quartz at 8 MHz
PLLXTPRE: no division
PLLSRC: HSE oscillator
PLLMUL = 9
SW = PLLCLK
AHB Prescaler = 1
APB1 Prescaler = 2
APB2 Prescaler = 1
What else?
There are some other blocks of the clocking system that we have not covered here that we would like to mention.
Clock security system (CSS) - translates roughly as "clocking security system". If, when using the HSE oscillator as a clock signal source for SYSCLK or PLL, there is a failure of HSE generation, CSS will automatically switch the whole system to work from the built-in RC oscillator HSI. Thus, if something happens to the quartz, the system will not hang up intentionally in an undefined state, but will be able to perform some actions, for example, to transfer the control object to a safe state (close all valves, shut down the power plants, etc.).
The RTC real-time clock module can be clocked from the built-in LSI oscillator at 40 kHz, from the HSE via a divider at 128, or from the LSE with an external quartz at 32768 Hz. The clock source is selected using RTCSEL.
The USB module receives the clock signal from the PLL, and when the PLL output frequency is 72 MHz, it is possible to activate the USB Prescaler with a division factor of 1.5 to obtain the required frequency of 48 MHz.
Microcontroller clock output (MCO) - microcontroller output to which you can output the frequency from one of the signal sources: SYSCLK, HSE, HSI or the signal from the PLL output, divided in half. The desired source is selected using MCO bits.
Conclusion
So, we have covered the main points in the clocking system of STM32 microcontrollers using STM32F103x8 and STM32F103xB as examples. In other STM32 microcontrollers it is about the same except for some nuances. In the next part, we will get acquainted with the clocking and reset registers of the RCC and look at an example of RCC initialization.
The clocking system in STM32 compared to AVR microcontrollers is quite intricate. Let's understand it.
Contents:
- Buses
- Generators
- Peripheral clocking
- SYSCLK signal sources
- HSE and PLL
- What else?
- Conclusion
In STM32 microcontrollers, all peripherals (I/O ports, timers, SPI interfaces, etc.) are connected to so-called buses, through which the peripherals receive clock signals and communicate with the bus master (e.g., the processor).
There are three main buses in the STM32F103x8: AHB, APB1 and APB2. Each bus has a certain group of devices hanging on it:
AHB: CPU core, memory, and DMA;
APB1: USART2, USART3, I2C1/2, CAN, timers TIM2..4;
APB2: GPIO ports, ADC, USART1, TIM1, SPI1.
In the datasheet for the STM32F103x8 there is a block diagram that shows which peripherals are connected where:
The diagram in Fig. 1 may seem complicated and incomprehensible at first, this is normal, in time everything will settle in your head and the feeling of incomprehension will disappear.
There is also this table, which also shows the peripheral devices and the buses to which they are connected:
It can be seen that in Fig. 2 the bus name (AHB, APB1 and APB2) has its maximum frequency in parentheses. Since the peripheral devices receive the clock signal from the bus, its frequency sets the speed of the devices connected to this bus. Below we will consider how to set the frequency of each of the microcontroller buses.
Another feature of the STM32 clocking system is that after the reset signal of the microcontroller all peripherals are in a disabled state and no clock signal is supplied to them. This is done in order to reduce power consumption of the entire microcontroller. Before you start working with any peripheral device, you must enable the clock signal to it. How to do this will be discussed below.
So, here are the main points to remember:
- All peripherals in STM32 microcontrollers are connected to the buses (AHB, APB1 and APB2), through which the interaction with the devices and the supply of clock signals to them;
- STM32 microcontroller buses can have different clocking frequencies;
- Before you start working with a peripheral device, you must enable the clock signal to it.
Several clock generators are present in the STM32F103x8/B microcontrollers:
The first of these is an 8 MHz internal RC oscillator called the High-speed internal (HSI) RC oscillator. After reset, the microcontroller is clocked from this oscillator by default. Its main advantage is that no additional external components are needed for the oscillator to work. However, its disadvantage is poor stability of the generated frequency: when the ambient temperature changes, its frequency of 8 MHz will float a bit. This may not be critical for devices not demanding time intervals, but in some cases this feature is unacceptable.
Next is the High-speed external (HSE). This oscillator is an alternative to HSI. It requires an external quartz resonator for 4-16 MHz. Its main advantage in comparison with HSI is the stability of the generated frequency. Also, with some customization, the OSC_IN pin can be connected to a source of a ready rectangular clock signal without using a resonator.
Next is the Low-speed external (LSE). This oscillator also requires an external quartz resonator, but only at 32768 Hz. The LSE is only used to clock the built-in RTC real-time clock, which can be used to clock the current time if needed.
The last oscillator is the low-speed internal (LSI) RC oscillator. This is a 40 kHz internal RC oscillator. It is not very accurate, but it has a very important task: generating a clock signal for the MC watchdog timer, which will restart the system in case of a hang-up. You can also clock the RTC from LSI, but most likely nobody will do this.
Peripheral clocking
The processor core and most peripherals use the SYSCLK clock signal.
After the AHB Prescaler, the clock signal is distributed among the microcontroller buses. The HCLK signal goes to the processor core, memory and the AHB bus periphery. FCLK also goes to the core. The clocking is fed to the Cortex System timer via a fixed divider by 8. The APB1 Prescaler generates the clocking signal for APB1 bus devices and the APB2 Prescaler for APB2 devices.
There is a small peculiarity of clock signal generation for timers and ADCs. The clock signal is applied to the timers as follows. If the bus divider (APB1 Prescaler or APB2 Prescaler) is set to one, the clocking frequency of the timers (TIMXCLK or TIM1CLK) will be equal to the bus frequency. But, if the divider is not equal to one, then the clocking frequency of the timers will be 2 times the bus frequency (see Figure 5, 6). This is how the ADC has its own divider, which forms the ADCCLK signal from the APB2 bus clock frequency (Fig. 6).
I think we should also pay attention to these elements of the block diagram:
These are nothing but devices for supplying a clock signal to a specific peripheral (2I logic elements). I will try to redraw one of them to make it clearer what it is and how it works:
Each peripheral module has its own bit in a special register (SPI1EN, IOPAEN, IOABEN and so on), which, when set to one, allows the clock signal to be applied to it. In Fig. 8 I have given an example only for the clock signal PCLK2 of the APB2 bus, for the other signals (HCLK, PCLK1, TIMXCLK, TIM1CLK) it is the same.
SYSCLK signal sources
So now we know that the main clock signal in STM32 microcontrollers is SYSCLK. Let's now understand how to get it. We have 3 options at our disposal: HSI, HSE and PLL generators:
After resetting the microcontroller, the built-in RC generator HSI is set as the default source of the SYSCLK signal. The clock signal flow for this case is shown in Fig. 10, the default values of all dividers are circled:
Now let's calculate the values of all frequencies in the default configuration. The frequencies of HCLK, FCLK, PCLK1, TIMXCLK, PCLK2, TIM1CLK will be equal to 8 MHz, the frequency of Cortex System timer is equal to 1 MHz, and ADCCLK is 4 MHz.
If we want to use the HSE generator, the picture is as follows:
When using an 8 MHz quartz resonator, all system frequencies will be the same as in the previous case. The only difference is that the frequency stability is better when using the HSE oscillator than when using HSI. However, if we want to maximize the performance of the whole system, we need to use a PLL frequency multiplier block as the SYSCLK source.
HSE and PLL
In STM32 microcontrollers, the PLL module can be clocked either from the HSI oscillator or from the HSE. There are a huge number of options for configuring the system clocking from the PLL. We will focus on only one, in which HSE is used and all coefficients are set to maximize system performance:
The quartz resonator is selected for 8 MHz. Next, the signal from the HSE without division (set by the PLLXTPRE bit) is fed to the PLLSRC selector and then to the PLL. In order to get 72 MHz from 8 MHz, the PLL multiplication factor must be PLLMUL=9. Next, the signal from the 72 MHz PLL goes to SYSCLK through the SW selector. Since we want to clock the processor core at a maximum frequency of 72 MHz, we set the AHB Prescaler equal to one (no division). To get the APB1 bus frequency equal to 36 MHz, we set APB1 Prescaler equal to 2. The APB2 bus has a maximum frequency of 72 MHz, so the APB2 Prescaler can be set to 1.
Total:
HSE quartz at 8 MHz
PLLXTPRE: no division
PLLSRC: HSE oscillator
PLLMUL = 9
SW = PLLCLK
AHB Prescaler = 1
APB1 Prescaler = 2
APB2 Prescaler = 1
What else?
There are some other blocks of the clocking system that we have not covered here that we would like to mention.
Clock security system (CSS) - translates roughly as "clocking security system". If, when using the HSE oscillator as a clock signal source for SYSCLK or PLL, there is a failure of HSE generation, CSS will automatically switch the whole system to work from the built-in RC oscillator HSI. Thus, if something happens to the quartz, the system will not hang up intentionally in an undefined state, but will be able to perform some actions, for example, to transfer the control object to a safe state (close all valves, shut down the power plants, etc.).
The RTC real-time clock module can be clocked from the built-in LSI oscillator at 40 kHz, from the HSE via a divider at 128, or from the LSE with an external quartz at 32768 Hz. The clock source is selected using RTCSEL.
The USB module receives the clock signal from the PLL, and when the PLL output frequency is 72 MHz, it is possible to activate the USB Prescaler with a division factor of 1.5 to obtain the required frequency of 48 MHz.
Microcontroller clock output (MCO) - microcontroller output to which you can output the frequency from one of the signal sources: SYSCLK, HSE, HSI or the signal from the PLL output, divided in half. The desired source is selected using MCO bits.
Conclusion
So, we have covered the main points in the clocking system of STM32 microcontrollers using STM32F103x8 and STM32F103xB as examples. In other STM32 microcontrollers it is about the same except for some nuances. In the next part, we will get acquainted with the clocking and reset registers of the RCC and look at an example of RCC initialization.