现在我们开始讲解SysTick定时器
那么什么是SysTick定时器呢
Systick定时器,是一个简单的定时器,对于CM3,CM4内核芯片,都有Systick定时器。
Systick定时器常用来做延时,或者实时系统的心跳时钟。这样做的好处是可以节省MCU资源,不用浪费一个定时器。比如UCOS中,分时复用,需要一个最小的时间戳,一般在STM32+UCOS系统中,都采用Systick做UCOS心跳时钟。
Systick定时器就是系统滴答定时器,一个24 位的倒计数定时器,计到0时,将从RELOAD 寄存器中自动重装载定时初值。(比如100从后往前数,数到0后再重装载到100,以此来形成永不停息的循环)
只要不把它在SysTick 控制及状态寄存器中的使能位清除,就永不停息,即使在睡眠模式下也能工作。
SysTick定时器被捆绑在NVIC中,用于产生SYSTICK异常(异常号:15)。[可以理解为SysTick是可以产生中断的,比如从100到0就可以中断一次]
Systick中断的优先级也可以设置。
sdfd
SysTick定时器有4个寄存器
分别是
控制及状态寄存器:SysTick_CTRL
重装载数值寄存器:SysTick_LOAD
当前数值寄存器:SysTick_VAL
校准数值寄存器:SysTick_CALRB
CTRL寄存器
*可以在Cortex-M3权威指南(中文)找到
位段0就是操纵是否使能的。位段1主要用于是否要使用中断。位段2中对于STM32外部时钟源是HCLK(AHB总线时钟)的1/8,内核时钟是HCLK时钟。
配置函数:SysTick_CLKSourceConfig();
段位16是在一个周期后给该位为1,如果再读取该位再清零,这可以防止误读。
LOAD寄存器
用以自动重装载值
VAL寄存器
就是读取当前值的
还有一个校准寄存器,但使用较少,就暂时不讲
SysTick库函数
固件库中的Systick相关函数:
SysTick_CLKSourceConfig()
//Systick时钟源选择 misc.c文件中
2. SysTick_Config(uint32_t ticks)
//初始化systick,时钟为HCLK,并开启中断
//core_cm3.h/文件中
Systick中断服务函数:
void SysTick_Handler(void);
下面开始分析
看到这个函数
它是用来选择时钟源的
配置的寄存器是Systick的CRTL寄存器
可以看到Systick的定义属于内核级别的
查看定义
有一个结构体类型
将寄存器名称和地址映衬
回到前面看它的入口参数
只能选择两种入口参数
这个在上文讲过
在系统时钟72M时
如果我们选择8分频的话
SysTick时钟就是9M
如果选择HCLK就直接是72M
再看这个函数
这个Systick_config有什么作用呢
它是开启Systick中断
使能Systick
以及配置Systick中断的时间多少
两个中断之间的时间间隔
中间能有几个Systick时钟周期
第一行代码是对有效性进行判断
因为systick是24位
是有范围的
看到下一句
LOAD用以设置重装载值
如果我们定时的值是1000
那么我们就需要给LOAD=999
主要因为这里的-1
然后设置优先级
具体下面讲
对于的分别是:
把VAL设置为0
选择时钟源
开启中断
使能定时器
现在我们看这样一个程序
static __IO uint32_t TimingDelay;//定义了TimingDelay这个变量
void Delay(__IO uint32_t nTime)//③我们需要使用这个函数,且有一个入口参数
{
TimingDelay = nTime;
while(TimingDelay != 0);//在这一块等中断,等到=0时就退出函数实现200ms延时
}
void SysTick_Handler(void)//④每到1ms就会用到这个中断
{
if (TimingDelay != 0x00)//这个变量只要不=0就-1
{
TimingDelay--;
}
}
int main(void)
{ …
if (SysTick_Config(SystemCoreClock / 1000)) //systick时钟为HCLK,中断时间间隔1ms①这是我们首先调用的函数,如果我们把systick时钟源设置为HCLK,那么在系统时钟中SystemCoreClock=72M,即72000000,我们除以1000设置为入口参数,也就是设置中断的时间间隔为1ms。72000/72000000=0.001s
{
while (1);
}
while(1)
{ Delay(200);//200ms//②在这里入口参数200进入函数
…
}
}
在我们原子的例程中
delay函数的编写方法是扫描查询
在delay.h中可以看到这些
然后我们看到delay.c
有OS的宏定义
这一块我们不讲
因为是实时系统的时候用的
我们只讲解基础的
首先上面定义了这两个因子
看到delay初始化函数
OS部分不看
看我们框起来的地方
首先选择Systick的时钟源
HCLK8分频就是9M
fac_us=9M/8000000=9
也就是1us=9个systick周期
因为us的因子是9
ms自然是其1000倍
然后看后面两个函数
delay_us的入口参数是有限制的
是2的24次方-1,
因为LOAD是24位的
delay_ms的入口参数也同理
函数的解释可以看注释
具体寄存器上面都讲过
函数就讲到这里
写好delay函数之后
进行调用需要delay.h头文件
在延时之前需要delay_init来初始化
初始化要选择时钟源和写因子
如果不初始化的话因子为0
延时就会错误