The original Article portal has five clock sources in stm32: Hsi, HSE, LSI, LSE, and PLL.
There are actually four clock sources, as shown in (gray-blue). The PLL is generated by the frequency doubling of the PLL circuit.① HSI is a high-speed internal clock, RC oscillator, with a frequency of 8 MHz. ② HSE is a high-speed external clock, which can be connected to a Z/Ceramic Resonator or an external clock source. The frequency range is 4 MHz ~ 16 MHz. ③ LSI is a low-speed internal clock, RC oscillator, and the frequency is 40 kHz. ④ LSE is a low-speed external clock, connected to a Z crystal with a frequency of 32.768khz. ⑤. The PLL is the frequency doubling output, and the clock input source can be HSI/2, HSE or HSE/2. The multiplier value can be 2 ~ 16 times, but its output frequency cannot exceed 72 MHz.
The LSI of 40 kHz is used by the independent watchdog iwdg. In addition, it can also be used as the real-time clock source of RTC. In addition, the real-time clock RTC clock source can also choose LSE, or HSE 128 division. The RTC clock source is selected through rtcsel [1:0. The stm32 has a full-speed USB Module, and its serial interface engine requires a 48 MHz clock source. The clock source can only be obtained from the PLL output end. It can be 1.5 or 1, that is, when the USB Module is required, the PLL must be enabled, and the clock frequency is set to 48 MHz or 72 MHz. In addition, stm32 can also select a clock signal to be output to the MCO foot (pa8), which can be a 2-division, Hsi, HSE, or system clock output for the PLL. The system clock sysclk is the clock source for the majority of Components in stm32 to work. The system clock can be PLL output, Hsi, or HSE. The maximum clock frequency of the system is 72 MHz, which is sent to each module after being divided by AHB divider, the AHB divider can be divided into 1, 2, 4, 8, 16, 64, 128, 256, and 512. The clock output by the AHB divider is sent to five modules: ①. The hclk clock is sent to the AHB Bus, kernel, memory, and DMA. ② The system timer clock sent to cortex after dividing the clock by 8. ③ The idle clock fclk sent directly to cortex. ④ Send it to the apb1 divider. You can select 1, 2, 4, 8, and 16 for the apb1 divider. The output path is used by apb1 peripherals (pclk1, with a maximum frequency of 36 MHz), and the output path is sent to the timer (timer) 2, 3, and 4 frequency divider. The frequency multiplier can be set to 1 or 2. The clock output is used by the Timer 2, 3, and 4. ⑤ Send it to the apb2 divider. Apb2 divider can be divided into 1, 2, 4, 8, and 16. The output channel is used by apb2 peripherals (pclk2, maximum frequency 72 MHz), and the other channel is sent to the timer (timer) 1 multiplier. The frequency multiplier can be set to 1 or 2. The clock output is used by the timer 1. In addition, the apb2 divider also provides a channel of output for the ADC divider, which is then sent to the ADC module. The ADC divider can be 2, 4, 6, or 8. Many of the above clock outputs are Band-enable control, such as the AHB Bus clock, kernel clock, various apb1 peripherals, and apb2 peripherals. When you need to use a module, remember to first enable the corresponding clock. Note that when the frequency of APB is 1, its frequency doubling value is 1; otherwise, its frequency doubling value is 2. Devices connected to apb1 (low-speed peripherals) include: power interface, backup interface, CAN, USB, i2c1, i2c2, uart2, uart3, spi2, window watchdog, timer2, timer3, timer4. Note that although the USB Module requires a separate 48 MHz clock signal, it should not be the clock for the USB Module to work, but only the clock for the Serial Interface Engine (SIE. The clock used by the USB module should be provided by apb1. Devices connected to apb2 (high-speed peripherals) include uart1, spi1, timer1, adc1, adc2, and all common Io ports (Pa ~ PE), the second function IO port. For single-chip microcomputer systems, clock settings for CPU, bus, and peripherals are very important, because there is no time series without a clock. Since the clock is an internal thing, the specific settings should start from the register.
RCC register structure, rcc_typedeff, which is defined in the file "stm32f10x. H" as follows: (v3.4 database) 1059 rows-> 1081 rows.
- Typedef struct
- {
- _ IO uint32_t CR;
- _ IO uint32_t cfgr;
- _ IO uint32_t CIR;
- _ IO uint32_t apb2rstr;
- _ IO uint32_t apb1rstr;
- _ IO uint32_t ahbenr;
- _ IO uint32_t apb2enr;
- _ IO uint32_t apb1enr;
- _ IO uint32_t bdcr;
- _ IO uint32_t CSR;
- # Ifdef stm32f10x_cl
- _ IO uint32_t ahbrstr;
- _ IO uint32_t cfgr2;
- # Endif/* stm32f10x_cl */
- # If defined (stm32f10x_ld_vl) | defined (stm32f10x_md_vl) | defined (stm32f10x_hd_vl)
- Uint32_t reserved0;
- _ IO uint32_t cfgr2;
- # Endif/* stm32f10x_ld_vl | stm32f10x_md_vl | stm32f10x_hd_vl */
- } Rcc_typedef;
Generally, an 8 MHz crystal oscillator is used on the board, and the maximum operating frequency of the Enhanced type is 72 MHz. It is obvious that the PLL frequency doubling is 9 times. These settings must be completed in the initialization phase. Set the clock parameters using the HSE clock:
1. Reset the RCC register to the default rcc_deinit;
2. Enable the external high-speed clock crystal oscillator HSE rcc_hseconfig (rcc_hse_on );
3. Wait for the external high-speed clock crystal oscillator to work hsestartupstatus = rcc_waitforhsestartup ();
4. Set the AHB clock rcc_hclkconfig;
5. Set the high-speed AHB clock rcc_pclk2config;
6. Set the low-speed AHB clock rcc_pclk1config;
7. Set PLL rcc_pllconfig;
8. Enable 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 a system clock while (rcc_getsysclksource ()! = 0x08)
12. Open the peripheral clock rcc_apb2periphclockcmd ()/rcc_apb1periphclockcmd (). For convenience, use the RCC setting function of the routine and explain it in Chinese annotations:
- Static void rcc_config (void)
- {
- /* Here RCC settings are reset, similar to register reset */
- Rcc_deinit ();
- /* Enable external high-speed crystal oscillator */
- Rcc_hseconfig (rcc_hse_on );
- /* Wait for high-speed crystal oscillator to stabilize */
- Hsestartupstatus = rcc_waitforhsestartup ();
- If (hsestartupstatus = success)
- {
- /* Enable Flash pre-read buffer */
- Flash_prefetchbuffercmd (flash_prefetchbuffer_enable );
- /* When flash is in the waiting state, 2 is for the high-frequency clock. The two sentences have no direct relationship with RCC and can be skipped for the moment */
- Flash_setlatency (flash_latency_2 );
- /* Hclk = sysclk set high-speed bus clock = system clock */
- Rcc_hclkconfig (rcc_sysclk_div1 );
- /* Pclk2 = hclk set low speed bus 2 clock = high speed bus clock */
- Rcc_pclk2config (rcc_hclk_div1 );
- /* Pclk1 = hclk/2 set the clock of the low speed bus 1 = the second division of the High Speed clock */
- Rcc_pclk1config (rcc_hclk_div2 );
- /* Adcclk = pclk2/6 set ADC peripheral clock = low speed bus 2 Six-division clock */
- Rcc_adcclkconfig (rcc_pclk2_div6 );
- /* Set PLL clock output to 72 MHz using HSE (8 MHz) as entry clock */
- // This sentence is critical.
- /* Use the phase-locked loop to increase the frequency of the external 8 MHz crystal oscillator by 9 to 72 MHz */
- Rcc_pllconfig (rcc_pllsource_hse_div1, rcc_pllmul_9 );
- /* Enable PLL */
- Rcc_pllcmd (enable );
- /* Wait till PLL is ready waiting for the stable output of the PLL */
- While (rcc_getflagstatus (rcc_flag_pllrdy) = reset)
- {}
- /* Select PLL as system clock source to set the output of the PLL to the system clock */
- Rcc_sysclkconfig (rcc_sysclksource_pllclk );
- /* Wait till PLL is used as system clock source waiting for verification to succeed */
- While (rcc_getsysclksource ()! = 0x08)
- {}
- }
- /* Enable FSMC, gpiod, gpioe, gpiof, gpiog and afio clocks */
- // Enable the peripheral interface bus clock. Pay attention to the subordinate situation of each peripheral. The distribution of different chips is different. You can check the manual at that time.
- Rcc_ahbperiphclockcmd (rcc_ahbperiph_fsmc, enable );
- Rcc_apb2periphclockcmd (rcc_apb2periph_gpiod | rcc_apb2periph_gpioe |
- Rcc_apb2periph_gpiof | rcc_apb2periph_gpiog |
- Rcc_apb2periph_afio, enable );
- }
From the above procedures, we can see that the system clock settings are complex. The more peripherals there are, the more factors to consider. At the same time, this setting is also rule-based, and the set parameters are also ordered and standardized. This should be noted in applications. For example, the setting of PLL must be before enabling, once the PLL is enabled, the parameters cannot be changed. After this setting, because my circuit board is an 8 MHz crystal oscillator, the system clock is 72 MHz, the high speed bus and low speed bus 2 are both 72 MHz, and the low speed bus 1 is 36 MHz, the ADC clock is 12 MHz, and the USB clock can transmit 48 MHz of data after 1.5 frequency division settings. For general clock settings, you must first consider the source of the system clock, whether it is an internal RC, an external crystal oscillator, or an external oscillator, and whether or not the PLL is required. Then consider the internal BUS and external bus, and finally consider the peripheral clock signal. Follow the principle of frequency doubling as the CPU clock, and then divide the clock from the inside to the outside. The principle of lower-level conversion is similar to the standardization requirement of PCB drawing. Note:
In stm32, devices connected to apb1 (low-speed peripherals) are: power interface, backup interface, CAN, USB, i2c1, i2c2, uart2, uart3, spi2, window watchdog, timer2, timer3, timer4.
Devices connected to apb2 (high-speed peripherals) include: GPIO_A-E, usart1, adc1, adc2, adc3, tim1, tim8, spi1, and all.
Program example:
Apb1 (low-speed peripherals)
Rcc_apb1periphclockcmd (rcc_apb1periph_can, enable );
Apb2 (high-speed peripherals)
Rcc_apb2periphclockcmd (rcc_apb2periph_gpioa, enable );
Rcc_apb2periphclockcmd (rcc_apb2periph_usart1 | rcc_apb2periph_gpioa, enable );
(Conversion) stm32 clock Analysis