This post was last edited by zhangbaoyin on 2023-6-11 22:52
Table of contents:
- Clock Tree Diagram
- The bus to which the peripheral is connected
- Steps to configure the system clock
- Get the system clock frequency
- System tick timer
- Update the running frequency during program running
The Arteli F435 microprocessor is an ARM CortexTM-M4F core, but its configurable clock flexibility is not inferior to that of the M7 core processor. The following is its clock block diagram:
From the figure we can see:
- The PLL multiplier has the following parameters: pre-allocation factor (/MS), multiplication factor (xNS), post-division factor (/FR). The PLL clock is output to the AHB bus.
- The clock input can be selected as HICK, HECK, LEXT, LICK, which are internal high-speed clock, external high-speed clock, external low-speed clock, and internal low-speed clock respectively. Among them, the clocks that can be connected to the PLL multiplication are the external high-speed clock (HECK) and the internal high-speed clock (HICK). The onboard external high-speed clock is recommended to be 8MHz , so that the multiplied clock can run at the full AHB bus speed of 288MHz; the chip's built-in internal high-speed clock is 48MHz . If PLL multiplication is required, the clock will be divided by 6 to 8MHz first, and then enter the PLL multiplication.
- The maximum clock rate of APB1/2 is 144MHz.
- The external high-speed clock (HECK) and the internal high-speed clock (HICK) can be directly connected to the AHB bus without going through PLL multiplication.
- The HICK oscillator clock is provided by the high-speed RC oscillator in the chip. The internal frequency of the HICK clock is 48MHz, and the frequency accuracy is poor, but the startup time is shorter than the HEXT crystal oscillator. The HICK clock frequency of each chip has been calibrated to 1% (25°C) before leaving the factory, and the factory calibration value is loaded into the HICKCAL[7:0] bit of the clock control register. Considering the impact of different voltages or ambient temperatures on the HICK RC oscillator, the user can adjust the HICK frequency through the HICKTRIM[5:0] bit in the clock control register. The HICK clock will not be released until it is stable.
- The bus to which the peripheral is connected
Starting from line 101 in the firmware library function at32f435_437_crm.h , there are bus connections for each peripheral. You can see that all GPIOs are connected to the high-speed bus AHB.
- Steps to configure the system clock
The configuration steps of reading the function system_clock_config() from the firmware library can be summarized as follows:
- system clock = (hext * pll_ns)/(pll_ms * pll_fr)
- system clock source = pll (hext)
- hext = 8000000
- sclk = 288000000
- ahbdiv = 1
- ahbclk = 288000000
- apb2div = 2
- apb2clk = 144000000
- apb1div = 2
- apb1clk = 144000000
- pll_ns = 144
- pll_ms = 1
- pll_fr = 4
- Calculate the system clock frequency to be configured
- Select clock source
- Select clock source frequency
- Confirm AHB, APB1/2 clock frequency
- Calculate PLL pre-allocation coefficient (/MS), multiplication coefficient (xNS), post-division coefficient (/FR)
Here are some PLL configuration options based on external 8M crystal oscillator that are set in the firmware library:
- Get the system clock frequency
After the system is reset, the default system clock is the internal high-speed clock (48M). Only when the user initializes the external clock and the external clock is stable, will it switch to the PLL external high-speed clock. To obtain the clock frequency, you need to call the void system_core_clock_update(void) function to update the global variables pll_clock_source, pll_ns, pll_ms, pll_fr, and pllrcsfreq after initializing the external clock. There is a method to use PLL to update the system clock frequency in line 135 of the system_at32f435_437.c file . The updated frequency will be saved in the global variable system_core_clock.
To get the system clock frequency, you can calculate it using these global variables:
AHB Clock
= PLL output clock
= PLL input clock x PLL multiplication factor / (PLL pre-scaling factor x PLL post-scaling factor)
= pll_clock_source * pll_ms / ( pll_ns * pll_fr )
The Systick timer is connected to the AHB bus, and the system tick timer (SysTick) uses HCLK or HCLK divided by 8 as the clock. The system tick timer is a 24-bit down counter, which can automatically reload the initial count value when it decrements to zero. It is easy to calculate that at 288MHz, using HCLK as the driving source, the maximum counting time is: (1<<24) / 288 = 58254us = 58ms . Therefore, in the delay_ms() function, if the counting period is greater than 50ms, it is necessary to count separately, update the reload counter every 50ms, and count the part less than 50ms according to delay_ms() .
- Update the running frequency during program running
Without further ado, let's look at the code
void updata_Sysclk(u16 freq)
{
/* reset crm */
crm_reset();
/* enable pwc periph clock */
crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE);
/* config ldo voltage */
pwc_ldo_output_voltage_set(PWC_LDO_OUTPUT_1V3);
/* set the flash clock divider */
flash_clock_divider_set(FLASH_CLOCK_DIV_3);
crm_clock_source_enable(CRM_CLOCK_SOURCE_HEXT, TRUE);
/* wait till hext is ready */
while(crm_hext_stable_wait() == ERROR);
/* config pll clock resource */
crm_pll_config(CRM_PLL_SOURCE_HEXT, freq, 1, CRM_PLL_FR_8);
/* enable pll */
crm_clock_source_enable(CRM_CLOCK_SOURCE_PLL, TRUE);
/* wait till pll is ready */
while(crm_flag_get(CRM_PLL_STABLE_FLAG) != SET);
/* config ahbclk */
crm_ahb_div_set(CRM_AHB_DIV_1);
/* config apb2clk, the maximum frequency of APB1/APB2 clock is 144 MHz */
crm_apb2_div_set(CRM_APB2_DIV_2);
/* config apb1clk, the maximum frequency of APB1/APB2 clock is 144 MHz */
crm_apb1_div_set(CRM_APB1_DIV_2);
/* enable auto step mode */
crm_auto_step_mode_enable(TRUE);
/* select pll as system clock source */
crm_sysclk_switch(CRM_SCLK_PLL);
/* wait till pll is used as system clock source */
while(crm_sysclk_switch_status_get() != CRM_SCLK_PLL);
/* disable auto step mode */
crm_auto_step_mode_enable(FALSE);
/* update system_core_clock global variable */
system_core_clock_update();
/* set the flash clock divider */
flash_clock_divider_set(FLASH_CLOCK_DIV_2);
}
After changing the system clock, be sure to reinitialize other hardware
void hardWareConfig(void)
{
at32_board_init();
uart_print_init(115200);
}
If you do not initialize other hardware, the following results are obtained: the serial port and delay do not operate normally:
d77be4b83396a396fdd88b534d6ab489
If you initialize other hardware, the result is as follows, the serial port and delay operate normally:
15f6dcd9b3bf2c744ecc86dedbbe49d2