SysTick定时器
SysTick定时器也叫SysTick滴答定时器,它是Cortex-M3内核的一个外设.它是一个24 位向下递减的定时器,每计数一次所需时间为1/SYSTICK,SYSTICK是系统定时器时钟,它可以直接取自系统时钟,还可以通过系统时钟8分频后获取。当定时器计数到0时,将从LOAD 寄存器中自重装定时器初值,重新向下递减计数,如此循环往复。如果开启SysTick中断的话,当定时器计数到0,将产生一个中断信号。因此只要知道计数的次数就可以准确得到它的延时时间。
SysTick定时器寄存器
1)CTRL寄存器
位段 | 名称 | 类型 | 复位值 | 描述 |
---|---|---|---|---|
16 | COUNTFLAG | R | 0 | 若在上次读取后,systick已经数到了0,则该位为1.如果读取本位,该位自动清零。 |
2 | CLKSOURCE | R/W | 0 | 0=外部时钟源 1=内核时钟源 |
1 | TICKINT | R/W | 0 | 1=SysTick倒数到0 产生SysTick异常请求 0=数到0无动作 |
0 | ENABLE | R/W | 0 | SysTick定时器的使能位 |
2)LOAD寄存器
位段 | 名称 | 类型 | 复位值 | 描述 |
---|---|---|---|---|
23:0 | RELOAD | R/W | 0 | 当倒数到0时,将被重载的值 |
SysTick定时器配置步骤
(1)设置SysTick定时器的时钟源。
void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)
参数:
#define SysTick_CLKSource_HCLK_Div8 ((uint32_t)0xFFFFFFFB)
#define SysTick_CLKSource_HCLK ((uint32_t)0x00000004)
(2)设置SysTick定时器的重装初始值(如果要使用中断的话,就将中断使能打开)。
SysTick->LOAD=nus*fac_us; //时间加载
(3)清零SysTick定时器当前计数器的值。
SysTick->VAL=0x00; //清空计数器
(4)打开SysTick定时器。
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数 SysTick_CTRL_ENABLE_Msk值为1
do
{
temp=SysTick->CTRL;
}
while((temp&0x01)&&!(temp&(1<<16)));//等待时间到达 CTRL的第16位是否为1
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL =0X00; //清空计数器
例:
void DelayInit()
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟 HCLK/8
fac_us=SystemCoreClock/8000000; //为系统时钟的1/8
fac_ms=(u16)fac_us*1000;//代表每个ms需要的systick时钟数
}
//延时n us
//n 为要延时的us数.
void DelayUs(unsigned long nus)
{
u32 temp;
SysTick->LOAD=nus*fac_us; //时间加载
SysTick->VAL=0x00; //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数
do
{
temp=SysTick->CTRL;
}
while(temp&0x01&&!(temp&(1<<16)));//等待时间到达
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
//延时n ms
//注意n ms的范围
//SysTick->LOAD为24位寄存器,所以,最大延时为:
//nms<=0xffffff*8*1000/SYSCLK
//SYSCLK单位为Hz,nms单位为ms
//对72M条件下,nms<=1864
void DelayMs(unsigned int nms)
{
u32 temp;
SysTick->LOAD=(u32)nms*fac_ms;//时间加载(SysTick->LOAD为24bit)
SysTick->VAL =0x00; //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数
do
{
temp=SysTick->CTRL;
}
while(temp&0x01&&!(temp&(1<<16)));//等待时间到达
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
void DelayS(unsigned int ns)//延时秒
{
unsigned char i;
for(i=0;i<ns;i++)
{
DelayMs(1000);
}
}