第六章 SysTick定时器
SysTick定时器(又名系统滴答定时器)是存在于Cortex-M3的一个定时器。24位,只能递减,嵌套在NVIC中,所有的Cortex-M内核的单片机都具有这个定时器。
只要是ARM Cotex-M系列内核的MCU都包含这个定时器。
使用内核的SysTick定时器来实现延时,可以不占用系统定时器,节约资源。在HAL库的毫秒级延时函数HAL_DRAYE()
,就是用滴答定时器实现的。
SysTick定时器是一个24位递减定时器,即计数器最大值为2^24,每个时钟周期减1,当减到0时,会产生Systick异常,同时再自动重载定时初值,开始新一轮计数,一旦SysTick定时器工作起来他是不会自动停下来的,除非将SysTick定时器的控制和状态位清零。
SysTick的时钟源有两个,一个是系统内核的时钟,一个是外部的系统时钟。
6.1STM32的SysTick定时器
6.1.1时钟来源
滴答定时器和普
通的定时器的工作流程是一样的,只不过系统定时器没有挂载到APB1或APB2上,他的时钟来源有两个,一个是经过AHB时钟8分频而来的(9MHz)。一个是直接连接AHB时钟(72MHz),具体情况通过寄存器配置。
通过设置SysTick定时器的计数初值和时钟频率就可以获得想要的计时时间。
HAL库提供HAL_SYSTICK_Config()
函数去设置这个初始值。
6.1.2 相关寄存器
对于SysTick的寄存器还是比较少的,只有4个,常用的有3个。
1、控制和状态寄存器(STK_CTRL)
CLKSOUECE是选择滴答定时器时钟源的,可以选择AHB(72MHz)或者AHB8分频(9MHz)。
TICKINT是设置当计数到0时,是否产生异常中断请求的。
ENABLE就是使能定时器的。
2、预装载值寄存器(STK_LOAD)
这个寄存器只有低24位能用,所以滴答定时器最大初值只能是2^24。当定时器计数到0时,就会把此寄存器里面的值重新装载进去,开始新一轮的计数。
3、当前值寄存器(STK_VAL)
这个寄存器是用来查看当前计数值的,定时器每计数一次,计数初值减1,这个当前寄存器中的计数值就加1,同样他的最大值也是2^24.
4、准校准值寄存器(STK_CALIB)
这个寄存器是用来校准的,一般用不到。
6.1.3计算计数初值
通过设置SysTick定时器的计数初值和时钟频率达到想要的计时时间。
假设滴答定时器时钟为72MHz,也就是计数1次要用1/72000000S,也就是1S计数72000000次,1ms计数72000次,1us计数72次。
将这这些初值值写入系统滴答定时器,定时器在每个时钟周期减1,减到0时,就刚好是对应事件,同时产生中断通知,再次加载计数初值如此反复。
HAL库提供HAL_SYSTICK_Config()
函数去设置这个初始值,里面的参数是计数值。
6.2HAL库配置SysTick定时器
HAL库中对SysTick定时器配置的函数常用以下四种。
下面进入HAL_SYSTICK_Config
函数看看HAL库中是如何配置SysTick定时器的。
他是通过调用ST官方提供的函数SysTick_Config
来配置的。
在SysTick_Config
中,首先将需要的计数初值放在预加载寄存器中,然后把当前值寄存器清零,然后设置控制和状态寄存器的第2、1、0位,设置滴答定时器时钟源来源为AHB不分频,即72MHz,允许中断请求,使能定时器。这样滴答定时器的时钟频率确定了,计数初值确定了,滴答定时器的定时时间就确定了。
可以调用 HAL_SYSTICK_CLKSourceConfig
这个函数修改滴答定时器的时钟源。
同之前的中断函数一样,滴答定时器也是在系统默认中断服务函数中调用HAL库的中断服务函数然后HAL中断函数在调用回调函数。
SysTick_Handler
–>HAL_SYSTICK_IRQHandler
–>HAL_SYSTICK_Callback
–>使用者自己代码。
但是HAL库对滴答定时器的依赖性挺强,好多地方都用到了滴答定时器,所以尽量不要对滴答定时器进行设置和使用,STM32F103定时器有8个,一般来说足够用了。