关于systick在Cortex-M4中有讲到,我们大家平常在单片机开发中经常会使用到延时函数,一般的,我们会使用变量自加循环判断的方法来实现软件延时。但是这种方法有个弊端——延时时间不精确。
主要体现在:
1、在C语言编写的延时函数中,每条函数语句的执行时间可能不同,这样,在实现延时的过程中,想通过增加或减少函数语句来实现延时的增加或减小控制起来不太方便,时间的精确性当然很难控制;
2、由于各种不同的控制器运行的主频可能不同,执行相同的延时函数所需要的的时间值可能就不同。这样,使得这种延时函数在不同的平台上移植起来时间的精确性就更不可靠。所以,我们就不使用这样的延时方法。
从ARM Cortex-M0内核开始,一直到现在的ARM Cortex-M4,这些内核中都搭载了systick滴答定时器,它放在了NVIC中,主要目的是为了给操作系统提供一个滴答中断。当然,毕竟它也是一个定时器,我们就可以利用它来做到精确的软件延时。
systick定时器是一个递减的计数器,如果设定初值并使能它以后,它会在每个系统时钟周期里计数器减1,直到减到0为止。然后,systick计数器自动重装初值并继续递减计数,如果软件上又使能了systick计数器的中断,那么,在systick计数器减到0的时候,中断被触发,当然,中断标志位也被置位。那么,每次计数器递减到0,所经过的时间值为:系统时钟周期*计数器初值。
systick定时器内部几个常用的寄存器:
1、systick控制及状态寄存器CTRL:
其中,CTRL[16]位是COUNTFLAG标志位,当systick计数到0的时候,该位置1,如果读取该位,则硬件自动清0,所以我们可以用软件判断是否计数到0。
CTRL[2]位是CLKSOURE标志位,用来指示当前systick定时器的时钟源,CLKSOURCE=1表示时钟源是内核时钟(一般我们会选择这种情况);CLKSOURCE=0表示时钟源是外部时钟源。
CTRL[1]位是TICKINT标志位,用来指示systick计数到0的时候是否产生systick异常请求。CTRL[0]位是ENABLE位,该位是systick定时器的使能位。
2、systick重装载计数器LOAD:
该寄存器是一个24位的寄存器,保存着systick定时器的初值,使得当systick计数到0的时候,将该寄存器中的数据重装载到当前计数器中继续递减计数。
3、systick当前数值计数器VAL:
该寄存器是一个24位的寄存器,用来指示当前的计数值。