SysTick的寄存器(24位,向下递减,每计数一次的时间是1/SYSTICK。当计数器到0时,将在LOAD寄存器中自动重装定时器初值,向下重新递减计数,如果开启SYSTICK中断的话,当定时器计数到0,将产生一个中断信号。因此只要知道计数次数就可以准确得到他的延时时间)
(1)CTRL寄存器
CTRL是SysTick定时器的控制及状态寄存器
(2)LOAD寄存器
LOAD是SysTick定时器的重装载数值寄存器
(3)VAL寄存器
VAL是SysTick定时器的当前数值寄存器
(4)CALIB寄存器
CALIB是SysTick定时器的校准数值寄存器
SysTick定时器操作步骤:
(1)设置SysTick定时器的时钟源(系统时钟或者系统时钟八分频后的时钟)
(2)设置SysTick定时器的重装初始值(如果要使用中断的话,就将中断使能打开)
(3)清零SysTick定时器当前计数器的值
(4)打开sysTick定时器
初始化SysTick:
如果系统采用168MHz,计时器使用系统频率8分频即21MHz,则每微妙计时器频率为21Hz。由于计数器为24位所以最多计数为2^24,即16777216,所以计时器所能计数的最大时长为798,915.04761904761904761904761905微秒即798.91504761904761904761904761905毫秒。
微秒延时函数:
毫秒延时函数:
超频使用时的毫秒延时函数:
在SysTick.c文件中定义函数:
#include "SysTick.h"
static u16 fac_us = 0;
static u16 fac_ms = 0;
void SysTick_Init(u8 SYSCLK)
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
fac_us=SYSCLK/8; //SYSCLK的8分频 保存1us所需的计数次数
fac_ms=(u16)fac_us*1000; //每个ms需要的systick时钟数
}
void delay_us(u32 nus)
{
u32 temp;
SysTick->LOAD=nus*fac_us; //时间加载
SysTick->VAL=0x00; //清空计数器
SysTick->CTRL|=0x01 ; //开始倒数
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达
SysTick->CTRL&=~0x01; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
void delay_nms(u16 nms)
{
u32 temp;
SysTick->LOAD=(u32)nms*fac_ms; //时间加载(SysTick->LOAD为24bit)
SysTick->VAL =0x00; //清空计数器
SysTick->CTRL|=0x01 ; //开始倒数
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达
SysTick->CTRL&=~0x01; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
void delay_ms(u16 nms)
{
u8 repeat=nms/540; //这里用540,是考虑到某些客户可能超频使用,
//比如超频到248M的时候,delay_nms最大只能延时541ms左右了
u16 remain=nms%540;
while(repeat)
{
delay_nms(540);
repeat--;
}
if(remain)delay_nms(remain);
}
注意在编译前要在在驱动文件里添加用于定义SysTick_CLKSourceConfig的misc.c文件