可以说,32系列的Systick就是一个加强功能了的51定时器。抛开HAL库不谈,Systick本身主要是寄托于三个寄存器运作的。本文章主要讲述运作框架;寄存器用法;Systick手动配置。
目录
1.Systick运作框架
先看图:
然后讲原理:
Systic本质上就是一个按照LOAD的值不断递减的一个时钟。其来源于HCLK(所以在配置的时候一定要初始化时钟树,否则频率未知),也就是说HCLK频率是多少,那么Systick的频率也是多少。然后VAL是一个记录器,就是说当前Systick的值是多少那么VAL就是多少。最后是countflag,当它为1时标志这此时VAL为了,将要reload。
2.SysTick的三个寄存器
CTRL
也是直接看图:
这里科普一个常识,寄存器是从0位开始算的,就象数组一样。
该寄存器主要配置SysTick中断,使能,分频。
VAL&LOAD
功能就和上述的一样,非常简单直接。
3.SysTick配置
在使用中,其实分两种情况:
一:单纯使用单片机的定时功能,用Systick重写delay函数。
二:在运行着操作系统的情况下(比如FreeRTOS)执行上述情况
先说情况一:
这种情况很简单,就是按照上述的情况来配置你的delay就行:
1.获取要演示的us--->2.按照频率对应到SysTick要记录的次--->3.清空当前SysTick的值--->4.使能定时器--->5.记录countflag值,当时间足够跳出定时--->6.关闭定时器.
直接上代码:
void delay_us(uint32_t nus){
uint32_t temp;
SysTick->LOAD = 72 * nus;
SysTick->VAL = 0x00;
SysTick->CTRL |= 1 << 2;
SysTick->CTRL |= 1 << 0;
do
{
temp = SysTick->CTRL;
} while ((temp & 0x01) && !(temp & (1 << 16)));
SysTick->CTRL &= ~(1<<0);
}
这里如果你对C中的按位操作不熟悉的话,很可能看不懂这里的部分配置,我稍微讲解一下:
对于
SysTick->CTRL |= 1 << 2; 给寄存器第三位(2)置1
SysTick->CTRL |= 1 << 0; 给寄存器第一位(0)置1
SysTick->CTRL &= ~(1<<0); 给寄存器第一位(0)置0
1<<0是在位的概念上把1左移0位。所谓在位的概念上,这个事情需要从定义来讲起:
定义一个变量比如char是1字节,就是8位。这里的八位就是二进制概念的八位。
也就是说,当你char一个变量a,在内存看来变量a就是0000 0000,当然了,肯定不都是0。
由于STM32中uint是指的无符号int类型,所以:
uint8 a = 1,在内存上就是 0000 0001,那么此时对 a << 1: 0000 0010;
仍然不理解,我回头再从新出一篇文章专门细讲这个。
再说情况二:
假设此时单片机上运行着一个FreeRTOS,那么此时是不可以随意的关闭再打开SysTick的。因为操作系统以SysTcik为时基。
所以我们在重写delay时有一个新的思路:我们不关心LOAD的值,不关心此时VAL的值,我们只关心在单位时间内,SysTcik记录了多少次就行。
直接上代码:
void delay_us(uint32_t nus)
{
uint16_t tnow,told,tcnt = nus*72; //这里*72是因为Systick的时钟来源是HLCK,
//而HLCK是72M也就是72*10^6,按照s和us的换算就是72
uint32_t load = SysTick->LOAD;
told = SysTick->VAL;
while(1){
tnow = SysTick->VAL;
if(tnow > told){
tcnt -= load + (tnow - told);
}else if(tnow < told){
tcnt -= told - tnow;
}
told = tnow;
if(tcnt <= 0) break;
}
}
看一遍代码就能看出思路,这里只说一个点:
当tnow<told时,说明此时在同意周期内。当tnow>told时,说明此时已经reload了一次。tnow在told之上,此时不能单纯计算差值,需要加上一个load值。
4.SysTick中断配置:
默认情况下,SysTick的中断被配置为1ms触发一次,配置的地方在这里:
按F12进入函数定义:
在STM32中,__weak就是用来给开发者重写函数的,所以如果你想要配置SysTick的中断服务部分,就在这里面配就行。
注意:这里的文件和函数位置都是HAL库版本的,至于标准库请再查询其他文章