一、什么是SysTick
1、Systick定时器也叫滴答定时器或者系统定时器,是一个24位的内核级别的倒计数定时器,从装载值倒计数到0时,再继续重装载值,只要不清除Systick使能位,就永不停息,常用做延迟和系统心跳时钟。
优点:节省MCU资源,不需要浪费一个定时器,,即使在睡眠模式下也能工作;捆绑在NVIC中断优先级管理,能产生Systick异常(即在每次计数到0时,可产生中断,编写相应的中断服务函数(SysTick_Handler(void)))即可,也可设置中断优先级。
二、 3个重要的Systick寄存器
1、 SysTick 控制和状态寄存器- CTRL
SysTick 控制和状态寄存器- CTRL位0:使能定时器
位1:设置是否产生中断
位2:0为外部时钟(即AHB/8,若外部时钟为72M,则SysTick时钟为其8分频的9M); 1为内核时钟。
位16:判断 SysTick 的当前值VAL计数器是否计到0的标志。
2、SysTick 重装载寄存器 -LOAD
SysTick 重装载寄存器 -LOAD3、SysTick 当前值寄存器-VAL
SysTick 当前值寄存器-VAL定时器工作方式:
如图1所示:每经过一个Systick时钟,VAL寄存器值-1,当VAL=0时(可产生中断),LOAD寄存器中的重装载值赋值给VAL寄存器作为初值再继续上面步骤。
三、怎么利用SysTick 做us和ms延时?
从上面的介绍已经知道了,用SysTick做延迟,取决于两个参数:SysTick的时钟周期 和 重装载值LOAD
1、首先我们要知道1us和1ms SysTick的延迟次数(分别需要几个SysTick时钟)
图2 延迟初始化函数如图2,如果不使用 OS(操作系统 )的时候,只是设置一下 SysTick 的时钟源(SYSCLK)以及确定 fac_us (1us 需要的SysTick时钟数目)和 fac_ms(1ms 需要的SysTick时钟数目) 的值。
1)、SysTick->CTRL&=~(1<<2);便是选择外部时钟作为SysTick时钟源,如果为72M,则它的时钟为9M.(对应周期为us级别)
2)、fac_us=SYSCLK/8;那么延迟1us,需要72/8=9次SysTick时钟周期
3)、fac_ms=(u16)fac_us*1000;则,延迟1ms,需要9000次SysTick时钟周期。
2、此时我们来看看实现延迟n us的函数(正点原子)如图3
图3 延迟 n(us)图3 的代码其实很简单只需要变化重装载值LOAD即可,1us需要fac_us次SysTick时钟,那么nus便需要nus*fac_us次SysTick时钟;装载好之后清空当前值寄存器VAL,再开启倒数功能,下面只需等待直到控制和状态寄存器CTRL第16位置1(即倒数到0),跳出循环,关闭计数器,清空VAL值便OK了。
3、实现延迟n ms的函数便是同理了,也是改变重装载计数器LOAD的值即可(用延迟1ms的SysTick时钟周期*n)。如图4
图4 延迟 n( ms )需要注意的是,重装载计数器LOAD是一个24位的计数器,装载的值不要超出即可(nms*fac_ms<=2^24和nus*fac_us<=2^24)。
最后如果想要调用两个延迟函数delay_ms()和delay_us(),得在主函数中先初始化即先执行delay_init()函数,来选择SysTick的时钟源,然后将两个因子fac_us (1us 需要的SysTick时钟数目)和 fac_ms(1ms 需要的SysTick时钟数目) 的值计算出来,再调用便好了。
网友评论