SysTick定时器
1. SysTick定时器的简介
是Cortex‐M3处理器内部一个简单的定时器。SysTick系统时钟位于Cortex-M3内核,是一个24位的递减计数器(从设定值一直做减法计数到零),是NVIC的一部分,根植于NVIC; 能够精确定时,为操作系统提供必要的时钟节拍。
主要用于: 精确延时,在多任务操作系统中为系统提供时间基准(时基); 任务切换,为每个任务分配时间片。
有4个寄存器控制SysTick定时器
具体代码在最后面
寄存器 | 含义 |
---|---|
CTRL | SysTick控制及状态寄存器 |
LOAD | SysTick重装载数值寄存器 |
VAL | SysTick当前数值寄存器 |
CALIB | SysTick校准数值寄存器 |
2. SysTick定时器的时钟来源
SysTick定时器的时钟源可以是内部时钟(FCLK)或者是外部时钟,系统默认的SysTick定时器是由AHB时钟(HCLK)8分频得到的,即SysTick的频率为9MHz。SysTick定时器从设定的初值计数到0时,会自动重装初值继续计数,同时触发中断,因此,只需确定计数的次数就可以精确得到延迟时间。
3. SysTick定时器寄存器的简介*
typedef struct
{
__IO uint32_t CTRL; //控制及状态寄存器
__IO uint32_t LOAD; //重装载数值寄存器
__IO uint32_t VAL; //当前数值寄存器
__I uint32_t CALIB; //校准数值寄存器,本章没有用到这个寄存器
} SysTick_Type;
4. SysTick定时器的编程步骤
1.确定 SysTick 时钟源,时钟频率
2.设置 重装载数值(LOAD)
3.设置 当前数值(VAL)
4.设置 SysTick 控制及状态(CTRL)使能
5.判断 SysTick 控制及状态寄存器的16位是否为1
6.当 SysTick 控制及状态寄存器的16位为1时,则将VAL清零并关闭 SysTick 控制及状态寄存器(CTRL)
5. 具体功能源代码
SysTick延时函数头文件
#ifndef _DELAY_H
#define _DELAY_H
#include "stm32f10x.h"
void Delay_Init(void);
void delay_us(uint32_t nus);
void delay_ms(uint32_t mus);
#endif
SysTick延时函数文件
#include "delay.h"
static uint8_t fac_us = 0;
static uint16_t fac_ms = 0;
// 1.确定 SysTick 时钟源,时钟频率
void Delay_Init(void)
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //确定时钟源
fac_us = SystemCoreClock / 8000000; //确定时钟频率,这里为微米级计数
fac_ms = (uint16_t)fac_us * 1000; //毫秒需要*1000,千进制
}
void delay_us(uint32_t nus)
{
u32 temp;
// 2.设置 重装载数值(LOAD),也就是你要设置的多少毫秒的数值
SysTick->LOAD = nus*fac_us;
// 3.设置 当前数值(VAL)
SysTick->VAL = 0X00;
//4.设置 SysTick 控制及状态(CTRL)使能。SysTick_CTRL_ENABLE_Msk左移1位
SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;
do
{
temp = SysTick->CTRL; //不断获取 SysTick 控制及状态(CTRL)的16位的值
}
//5.判断 SysTick 控制及状态寄存器的16位是否为1
while(!(temp&(1<<16)));
//6.当 SysTick 控制及状态寄存器的16位为1时,则将VAL清零并关闭 SysTick 控制及状态寄存器(CTRL)
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL = 0X00;
}
//与void delay_us(uint32_t nus)的配置方法基本相同
void delay_ms(uint32_t mus)
{
u32 temp;
SysTick->LOAD = mus*fac_ms;
SysTick->VAL = 0X00;
SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;
do
{
temp = SysTick->CTRL;
}while(!(temp&(1<<16)));
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL = 0X00;
}