STM32——时钟树、时钟系统、滴答定时器

这篇文章介绍了32的时钟,所谓时钟就是32的各种片上外设功能的频率,配置频率可以说是各种外设初始化的第一步

STM32时钟系统

  1. STM32 有5个时钟源:HSI、HSE、LSI、LSE、PLL。
    ①、HSI是高速内部时钟,RC振荡器,频率为8MHz,精度不高。
    ②、HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时 钟源,频率范围为4MHz~16MHz。
    ③、LSI是低速内部时钟,RC振荡器,频率为40kHz,提供低功耗时钟。WDG
    ④、LSE是低速外部时钟,接频率为32.768kHz的石英晶体。RTC
    ⑤、PLL为锁相环倍频输出,其时钟输入源可选择为HSI/2、HSE或者HSE/2。倍频可选择为2~16倍,但是其输出频率最大不得超过72MHz。
  2. 系统时钟SYSCLK可来源于三个时钟源:
  3. ①、HSI振荡器时钟
    ②、HSE振荡器时钟
    ③、PLL时钟
  4. STM32可以选择一个时钟信号输出到MCO脚(PA8)上,可以选择为PLL输出的2分频、HSI、HSE、或者系统时钟。
  5. 任何一个外设在使用之前,必须首先使能其相应的时钟。
    时钟系统框图

重要的时钟有:

  • SYSCLK(系统时钟)
  • AHB总线时钟
  • APB1总线时钟(低速): 速度最高36MHz
  • APB2总线时钟(高速): 速度最高72MHz
  • PLL时钟

时钟配置文件

头文件: stm32f10x_rcc.h 和 源文件:stm32f10x_rcc.c
在这里插入图片描述

时钟系统初始化函数

函数SystemInit在系统启动之后会在汇编代码中自动调用,启动文件中的汇编代码指定了系统启动的初始地址
路径
汇编

该函数定义在startup_stm32f10x_xx.s文件中,
时钟初始函数
函数定义了以下时钟的频率,初始化后的状态如图:
速率

初始化之前首先通过宏定义定义系统时钟频率:
#define SYSCLK_FREQ_72MHz 72000000

初始化之后可以通过变量SystemCoreClock获取系统变量。如果SYSCLK=72MHz,那么变量SystemCoreClock=72000000。

滴答定时器

  1. Systick定时器,是一个简单的定时器,Systick定时器常用来做延时,或者实时系统的心跳时钟。这样可以节省MCU资源,不用浪费一个定时器。比如UCOS中,分时复用,需要一个最小的时间戳,一般在STM32+UCOS系统中,都采用Systick做UCOS心跳时钟。

  2. Systick定时器就是系统滴答定时器,一个24 位的倒计数定时器,计到0 时,将从RELOAD 寄存器中自动重装载定时初值。只要不把它在SysTick 控制及状态寄存器中的使能位清除,就永不停息,即使在睡眠模式下也能工作。

  3. SysTick定时器被捆绑在NVIC中,用于产生SYSTICK异常(异常号:15)。Systick中断的优先级也可以设置。

4个有关Systick的寄存器
在这里插入图片描述

CTRLSysTick 控制和状态寄存器
LOADSysTick 自动重装载除值寄存器
VALSysTick 当前值寄存器
CALIBSysTick 校准值寄存器

配置CLKSOURCE时,外部时钟源是 HCLK(AHB总线时钟)的1/8,内核时钟是 等于HCLK时钟的
配置函数SysTick_CLKSourceConfig(),在misc.c文件中

Systick相关函数:

//  在misc.c文件中
//Systick时钟源选择
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;
  }
}
 //在core_cm3.h/core_cm4.h文件中
//初始化systick,时钟为HCLK,LOAD,VAL,CTRL并开启中断
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{ 
  if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            /* Reload value impossible */
                                                               
  SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      /* set reload register */
  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Cortex-M0 System Interrupts */
  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 */
}

Systick中断服务函数

用中断的方式实现延时,此方法浪费资源

//默认在stm32f10x.c中
static __IO uint32_t TimingDelay;
void Delay(__IO uint32_t nTime)
{
   TimingDelay = nTime;
   while(TimingDelay != 0);
}
void SysTick_Handler(void)
{
    if (TimingDelay != 0x00) 
     { 
       TimingDelay--;
     }
}
 int main(void)
 {if (SysTick_Config(SystemCoreClock / 1000)) //systick时钟为HCLK,中断时间间隔1ms
     {
     while (1);
     }
    while(1)
     { Delay(200);//2ms}
}

时钟频率

采用查询方式实现延时,看正点原子代码

void delay_init()
{
#if SYSTEM_SUPPORT_OS  							//如果需要支持OS.
	u32 reload;
#endif
	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);	//选择外部时钟  HCLK/8
	fac_us=SystemCoreClock/8000000;				//为系统时钟的1/8  
#if SYSTEM_SUPPORT_OS  							//如果需要支持OS.
	reload=SystemCoreClock/8000000;				//每秒钟的计数次数 单位为M  
	reload*=1000000/delay_ostickspersec;		//根据delay_ostickspersec设定溢出时间
												//reload为24位寄存器,最大值:16777216,在72M下,约合1.86s左右	
	fac_ms=1000/delay_ostickspersec;			//代表OS可以延时的最少单位	   

	SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;   	//开启SYSTICK中断
	SysTick->LOAD=reload; 						//每1/delay_ostickspersec秒中断一次	
	SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;   	//开启SYSTICK    

#else
	fac_ms=(u16)fac_us*1000;					//非OS下,代表每个ms需要的systick时钟数   
#endif
}	
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值