STM32学习笔记:SysTick时钟

SysTick时钟,俗称“嘀嗒定时器”,它能按固定的时间产生一次中断,通常是多长时间产生一次中断呢?官方给出的一个时间是1ms

那么,它是怎么准确的产生1ms的呢.. 先来看看这家伙在时钟树的哪里吧
这里写图片描述
它是由HCLK/8得到的,也就是:72MHz/8=9MHz。
我们还能在STM32手册上找到这么一句话:系统嘀嗒校准值固定位9000,当系统嘀嗒时钟设为9MHz,产生1ms时间基准.
让我们来看看9000是怎么来的,这里要看下SysTick寄存器的配置了:
这里写图片描述
可以看到SysTick共有4个寄存器.
这里写图片描述
这里写图片描述
这里写图片描述
注意看上面的CTRL寄存器的CLKSOURCE位(时钟源位),它有两个选择,一个是内核时钟源FLCK(72MHz),一个是外部时钟源HCLK,这里应该是

分频以后的了,所以应该是HCLK/8(9MHz);注意这里,这里选不同的值,重装寄存器里的值也是不同的.到下面配置的时候再说说.

好,那么我们来解释下9000的固定校准值是怎么来的:
我们知道,我们设定一个计数, 那么每次计数器减到 0 ,时间经过了:系统时钟周期 * 计数器初值. 我们使用 72M 作为系统时钟, 那么每次计数器减 1 所用的时间是 1/72M , 计数器的初值如果是 72000 ,那么每次计数器减到 0 ,时间经过 (1/72M)*72000= 0.001 , (简单理解:用 72M 的时钟频率,即 1s 计数 72M=72000000 次,那 1ms 计数 72000 次,所以计数值为 72000 ) ,那么它的固定校准值是怎么来的呢..其实我也不知道的,可能和8分频有关系吧..
让我们来看看这些寄存器的配置:
系统库core_cm3.h中

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 Control / Status Register Definitions */
#define SysTick_CTRL_COUNTFLAG_Pos         16                                             /*!< SysTick CTRL: COUNTFLAG Position */
#define SysTick_CTRL_COUNTFLAG_Msk         (1ul << SysTick_CTRL_COUNTFLAG_Pos)            /*!< SysTick CTRL: COUNTFLAG Mask */

#define SysTick_CTRL_CLKSOURCE_Pos          2                                             /*!< SysTick CTRL: CLKSOURCE Position */
#define SysTick_CTRL_CLKSOURCE_Msk         (1ul << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */

#define SysTick_CTRL_TICKINT_Pos            1                                             /*!< SysTick CTRL: TICKINT Position */
#define SysTick_CTRL_TICKINT_Msk           (1ul << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */

#define SysTick_CTRL_ENABLE_Pos             0                                             /*!< SysTick CTRL: ENABLE Position */
#define SysTick_CTRL_ENABLE_Msk            (1ul << SysTick_CTRL_ENABLE_Pos)               /*!< SysTick CTRL: ENABLE Mask */

/* SysTick Reload Register Definitions */
#define SysTick_LOAD_RELOAD_Pos             0                                             /*!< SysTick LOAD: RELOAD Position */
#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFul << SysTick_LOAD_RELOAD_Pos)        /*!< SysTick LOAD: RELOAD Mask */

/* SysTick Current Register Definitions */
#define SysTick_VAL_CURRENT_Pos             0                                             /*!< SysTick VAL: CURRENT Position */
#define SysTick_VAL_CURRENT_Msk            (0xFFFFFFul << SysTick_VAL_CURRENT_Pos)        /*!< SysTick VAL: CURRENT Mask */

就拿CTRL吧.. 从上面的寄存器图上可以看到,它只需要配置4个位,即:16、2、1、0位,其它的保留不变不用

#define SysTick_CTRL_CLKSOURCE_Pos          2                                             /*!< SysTick CTRL: CLKSOURCE Position */ 

#define SysTick_CTRL_CLKSOURCE_Msk         (1ul << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */ 

ul是unsigned long 型, 这两行代码的意思是1左移2位,也就是将2这位置1,这里就是选择了内核时钟源FCLK(72MHz),所以我们要把计数初值设置为72000,这样才能

产生1ms的基准时钟哦~ 当然,如果这里将1改为0,那么就要将计数初值设为9000了~ 哟西~~

你可能感兴趣的:(STM32)