STM32----系统时钟与Systick定时器

  • 系统时钟

1. STM32 有5个时钟源:HSI、HSE、LSI、LSE、PLL。    

①、HSI是高速内部时钟,RC振荡器,频率为16MHz,精度不高。可以直接作为系统时钟或者用作PLL时钟输入。  

②、HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~26MHz。  

③、LSI是低速内部时钟,RC振荡器,频率为32kHz,提供低功耗时钟。主要供独立看门狗和自动唤醒单元使用。  

④、LSE是低速外部时钟,接频率为32.768kHz的石英晶体。RTC  

⑤、PLL为锁相环倍频输出。STM32F4有两个PLL: (主PLL(PLL)由HSE或者HSI提供时钟信号,并具有两个不同的输出时钟。)

       第一个输出PLLP用于生成高速的系统时钟(最高168MHz)

       第二个输出PLLQ用于生成USB OTG FS的时钟(48MHz),随机数发生器的时钟和SDIO时钟。

2. 系统时钟SYSCLK可来源于三个时钟源:        

①、HSI振荡器时钟        

②、HSE振荡器时钟        

③、PLL时钟

3.STM32F4时钟信号输出MCO1(PA8)和MCO2(PC9)。

MCO1:用户可以配置预分频器(1~5)向MCO1引脚PA8输出4个不同的时钟源:HIS,LSE,HSE,PLL 

MCO2:用户可以配置预分频器(1~5)向MCO2引脚PC9输出4个不同的时钟源:HSE,PLL,SYSCLK,PLLI2S  

MCO最大输出时钟不超过100MHz

4.任何一个外设在使用之前,必须首先使能其相应的时钟。

 

SystemInit函数:

系统时钟初始化函数:SystemInit();  

使用库函数的时候,在系统启动之后会自动调用:startup_stm32f40_41xxx.s文件中:

; Reset handler
Reset_Handler    PROC
                 EXPORT  Reset_Handler             [WEAK]
        IMPORT  SystemInit
        IMPORT  __main

                 LDR     R0, =SystemInit
                 BLX     R0
                 LDR     R0, =__main
                 BX      R0
                 ENDP

 

首先如果使用外部时钟源HSE,要配置外部晶振频率:    

stm32f4xx.h       

#if !defined  (HSE_VALUE) 
       #define HSE_VALUE    ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
       #endif /* HSE_VALUE */

 

初始化之前首先通过宏定义定义下面变量来定义系统时钟频率:

#define PLL_M      8
#define PLL_Q      7
#define PLL_N      336
#define PLL_P      2
PLL=8MHz * N/ (M*P)=8MHz* 336 /(8*2) = 168MHz

 

初始化之后的状态:     
 

SYSCLK(系统时钟)                 =168MHz     

AHB总线时钟(HCLK=SYSCLK)           =168MHz     

APB1总线时钟(PCLK1=SYSCLK/4)       =42MHz     

APB2总线时钟(PCLK2=SYSCLK/2)       =84MHz     

PLL主时钟                          =168MHz 

 

初始化之后可以通过变量SystemCoreClock获取系统变量。

如果SYSCLK=168MHz,那么变量SystemCoreClock=168000000。

 

  • Systick定时器

       Systick定时器,是一个简单的定时器,对于CM3,CM4内核芯片,都有Systick定时器。 Systick定时器常用来做延时,或者实时系统的心跳时钟。这样可以节省MCU资源,不用浪费一个定时器。比如UCOS中,分时复用,需要一个最小的时间戳,一般在STM32+UCOS系统中,都采用Systick做UCOS心跳时钟。Systick定时器就是系统滴答定时器,一个24 位的倒计数定时器,计到0 时,将从RELOAD 寄存器中自动重装载定时初值。只要不把它在SysTick 控制及状态寄存器中的使能位清除,就永不停息,即使在睡眠模式下也能工作。

 

4个Systick寄存器:

CTRL   SysTick 控制和状态寄存器  LOAD        

SysTick 自动重装载除值寄存器 VAL    

SysTick 当前值寄存器  CALIB      

SysTick 校准值寄存器

 

SysTick 控制和状态寄存器- CTRL

STM32----系统时钟与Systick定时器_第1张图片

对于STM32,外部时钟源是 HCLK(AHB总线时钟)的1/8内核时钟是 HCLK时钟      配置函数:SysTick_CLKSourceConfig();

 

SysTick 重装载数值寄存器- LOAD

 

SysTick 当前值寄存器- VAL

STM32----系统时钟与Systick定时器_第2张图片

 

  SysTick_CLKSourceConfig函数:

void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)
{
  /* Check the parameters */
  assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));

  if (SysTick_CLKSource == SysTick_CLKSource_HCLK)
  {
    SysTick->CTRL |= SysTick_CLKSource_HCLK;
  }
  else
  {
    SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8;
  }
}

static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{ 
  if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);         /* Reload value impossible */
   
 /* set reload register */                                                            
  SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; 
/* set Priority for Cortex-M0 System Interrupts */
  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); 
  SysTick->VAL   = 0;                                        /* Load the SysTick Counter Value */
  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk | 
                   SysTick_CTRL_TICKINT_Msk   | 
                   SysTick_CTRL_ENABLE_Msk;     /* Enable SysTick IRQ and SysTick Timer */
  return (0);                                                  /* Function successful */
}

 

你可能感兴趣的:(MCU)