STM32 clock configuration and SysTick configuration_based on STM32F103

【I. Introduction

  • When programming STM32 front-end and back-end programs, the most basic configuration should be the configuration of its clock and system timer. For the standard library, call SysTick_Init ();. If the HAL library is used, HAL_Init() should be called first; to initialize the HAL library.
  • The standard library is used here.

[2] STM32 clock configuration

1 Overview

  • The clock controller in RCC (Reset Clock Controller) mainly focuses on the clock tree.
  • General configuration: PCLK2 (APB2 peripheral)=HCLK (SDIO peripheral clock only)=SYSCLK (system clock)=PLLCLK=72MHz, PCLK1=HCLK/2=36MHz.
  • Explanation of various clocks:
    Note 1: HSE (High speed external clock): High speed external clock. Provided by external crystal oscillator through OSC_IN and OSC_OUT. If it is a passive crystal oscillator, connect two pins; if it is an active crystal oscillator, connect it to OSC_IN, and the other one is left floating. Generally, a passive crystal oscillator of 8MHz is used.
    Note 2: LSE (Low speed external clock): Low speed external clock. Provided by the external crystal oscillator through OSC32_IN and OSC32_OUT, generally 32.768KHz, provides the clock of the RTC.
    Note 3: HSI (High speed internal clock): High speed internal clock, 8MHz, can be used as a backup. When the HSE fails, when the CSS and CSS interrupts are enabled, the HSI can provide the system running clock, but the maximum can only be 64MHz.
    Note 4: LSI (Low speed internal clock): Low speed internal clock, 40KHz, provided for independent watchdog.
    Note 5: PLL (phaselocked loop): phase-locked loop frequency multiplication output. Provided by HSE or HSI/2, it can be set to 2~16 times of output. Generally, the HSE path is selected, and the frequency is 9 times (72MHz).
    1.PCLK2 (Peripheral Clock 2): The clock of APB2 (Advanced Peripheral Bus, Advanced Peripheral Bus), the clock provided to peripherals, such as GPIO/USART1/SPI1, etc. Generally set to a frequency division, 72MHz.
    2. HCLK (High Performance Clock): The clock of AHB (Advanced High Performance Bus, advanced high-performance bus), the clock provided to the AHB bus, core memory, DMA, etc., can be obtained by dividing the frequency by the AHB prescaler.
    3.PCLK(Peripheral Clock): Peripheral bus clock, which is low-rate, provided to USART2/3/4/5, SPI2/3, IIC1/2, etc.
    Functions about system clock configuration exist in the library function system_stm32f10x.c.
    write picture description here

2. Clock configuration

  • For the standard library, if a clock frequency is defined, the system will initialize the clock frequency by default.

In system_stm32f10x.c:

#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
/* #define SYSCLK_FREQ_HSE    HSE_VALUE */
 #define SYSCLK_FREQ_24MHz  24000000
#else
/* #define SYSCLK_FREQ_HSE    HSE_VALUE */
/* #define SYSCLK_FREQ_24MHz  24000000 */ 
/* #define SYSCLK_FREQ_36MHz  36000000 */
/* #define SYSCLK_FREQ_48MHz  48000000 */
/* #define SYSCLK_FREQ_56MHz  56000000 */
#define SYSCLK_FREQ_72MHz  72000000
#endif
#ifdef SYSCLK_FREQ_HSE
  uint32_t SystemCoreClock         = SYSCLK_FREQ_HSE;        /*!< System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_24MHz
  uint32_t SystemCoreClock         = SYSCLK_FREQ_24MHz;        /*!< System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_36MHz
  uint32_t SystemCoreClock         = SYSCLK_FREQ_36MHz;        /*!< System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_48MHz
  uint32_t SystemCoreClock         = SYSCLK_FREQ_48MHz;        /*!< System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_56MHz
  uint32_t SystemCoreClock         = SYSCLK_FREQ_56MHz;        /*!< System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_72MHz
  uint32_t SystemCoreClock         = SYSCLK_FREQ_72MHz;        /*!< System Clock Frequency (Core Clock) */
#else /*!< HSI Selected as System Clock source */
  uint32_t SystemCoreClock         = HSI_VALUE;        /*!< System Clock Frequency (Core Clock) */
#endif
#ifdef SYSCLK_FREQ_HSE
  static void SetSysClockToHSE(void);
#elif defined SYSCLK_FREQ_24MHz
  static void SetSysClockTo24(void);
#elif defined SYSCLK_FREQ_36MHz
  static void SetSysClockTo36(void);
#elif defined SYSCLK_FREQ_48MHz
  static void SetSysClockTo48(void);
#elif defined SYSCLK_FREQ_56MHz
  static void SetSysClockTo56(void);  
#elif defined SYSCLK_FREQ_72MHz
  static void SetSysClockTo72(void);
#endif

As can be seen from these three pieces of code, if SYSCLK_FREQ_72MHz is defined, the SetSysClockTo72(void); function will be called. See the function description of this function below:

/**
  * @brief  Sets System clock frequency to 72MHz and configure HCLK, PCLK2 
  *         and PCLK1 prescalers. 
  * @note   This function should be used only after reset.
  * @param  None
  * @retval None
  */
  ……

In summary, the system clock can be set by defining the clock frequency, which are all functions that have been written by the standard library.

3. Clock output

Configure PA8 multiplexing as MCO pin output:

void MCO_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStructure);
}

[3] STM32 SysTick system timer configuration

  • SysTick is the core peripheral of CM3. It is a 24-bit down-counter, and each count time is 1/SYSCLK, which is 1/72000000.
  • Calculation of SysTick count time: t=reload value*1/AHB clock frequency. 1/AHB clock frequency is the time to count once. Generally, the reload value is set as 72000000/100000=720, then 10us is interrupted once; generally it is not set as 1us interrupt once, so the interrupt frequency is too high, and the program center of gravity is shifted.
  • Timer configuration steps:
    1. Initialization:
/**
  * @brief  启动系统滴答定时器SysTick
  * @param  none
  * @retval none
  */
void SysTick_Init( void )
{
    /* SystemFrequency / 1000    1ms
     * SystemFrequency / 100000  10us
     * SystemFrequency / 1000000 1us
     */
    if ( SysTick_Config(SystemCoreClock / 100000) ) 
    { 
        /* Capture error */ 
        while (1);
    }
    //关闭滴答定时器
    SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;
}

2. Timing function:

/**
  * @brief   10us延时程序
  * @param  
  * @arg nTime: Delay_10us( 1 ) 为10us
  * @retval  none
  */
void Delay_10us( __IO u32 nTime )
{ 
    TimingDelay = nTime;    

    //使能滴答定时器
    SysTick->CTRL |=  SysTick_CTRL_ENABLE_Msk;

    while( TimingDelay != 0 );
}

3. Interrupt service function:

static __IO u32 TimingDelay = 0;
/**
  * @brief  This function handles SysTick Handler.
  * @param  None
  * @retval None
  */
void SysTick_Handler(void)
{
    TimingDelay_Decrement();    
}
/**
 * @brief  获取节拍程序,10us减1
 * @param  none
 * @retval none
 * @attention 在SysTick_Handler()中调用
  */
void TimingDelay_Decrement(void)
{
    if ( TimingDelay != 0x00 )
    { 
        TimingDelay --;

    }
    if(TimeLapseflag != 0x00)
    {
        TimeLapseflag --;
    }
}
  • Another microsecond-level timing programming:
void SysTick_Delay_Us( __IO uint32_t us)
{
    uint32_t i;
    SysTick_Config(SystemCoreClock/1000000);

    for(i=0;i<us;i++)
    {
        //当计数器的值减到0时,CTRL寄存器的位16会置1
        while(!((SysTick->CTRL)&(1<<16)));
    }
    SysTick->CTRL &=~SysTick_CTRL_ENABLE_Msk;
}

In the same way, you can write ms-level timing programs.


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325600663&siteId=291194637