CKS32F4xx系列MCU SysTick定时器的原理及使用方法

描述

本课将为大家讲解CKS32F4xx系列产品的SysTick定时器原理及使用方法。SysTick定时器也叫SysTick滴答定时器,属于Cortex-M4内核外设。SysTick定时器可以用于查询延时、中断延时以及测量函数运行时间;在实时操作系统RTOS中作为滴答定时器,用于上下文切换。采用Cortex-M内核的微处理都有SysTick定时器,方便不同处理器之间的软件移植。SysTick定时器时钟源可直接选取系统时钟,还可以通过系统时钟8分频后取得。

SysTick定时器内部是一个递减的计时器,当减到0时,将从LOAD寄存器中自动重装定时器初始值,重新向下递减计数,如此循环往复。如果开启SysTick中断,当计数器减到0时,SysTick可以生产异常,异常编号为15。

SysTick定时器寄存器

SysTick定时器内部是一个24位向下递减的计时器,包含4个寄存器,如图。

mcu

图1 SysTick定时器框图

1)STK_CTRL寄存器

STK_CTRL是SysTick定时器的控制及状态寄存器,相应功能如下:

mcu

2) STK_LOAD寄存器

STK_LOAD寄存器是SysTick定时器的重装载数值寄存器,相应功能如下:

mcu

3)STK_VAL寄存器

STK_VAL寄存器是SysTick定时器的当前数值寄存器,相应功能如下:

mcu

4)STK_CALIB寄存器

STK_CALIB寄存器是SysTick定时器的校准数值定时器,用于利用片上硬件为软件提供校准信息,但使用情况较少。在CMSIS Core中,不需要使用SysTick校准寄存器,因为CMSIS Core提供了一个名为“SystemCoreClock”的软件变量。此变量在系统初始化函数“SystemInit()”中设置,每次更改系统时钟配置时也会更新。这种方法比使用SysTick CalibrationRegister的硬件方法灵活。校准寄存器描述如下表:

mcu

查询延时使用步骤

1)配置SysTick定时器时钟源

2)加载延时计数值 3)清零计数器,启动定时器开始递减计数 4)等待计数结束 5)清零计数,关闭定时器,延时结束 相关函数如下:

 

void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)
{
  if (SysTick_CLKSource == SysTick_CLKSource_HCLK)
  {
    SysTick->CTRL |= SysTick_CLKSource_HCLK;
  }
  else
  {
    SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8;
  }
}
void TickDelayInit(u8 SYSCLK)
{
//选择时钟源为AHB/8
    SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
fac_us=SYSCLK>>3;
fac_ms=((u32)SYSCLK*1000)>>3;
}
void TickDelayUs(u16 nus)
{
uint32_t temp;
SysTick->LOAD=nus*fac_us-1;
SysTick->VAL=0x00;
SysTick->CTRL=0x01;
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16)));
SysTick->CTRL=0x00;        
SysTick->VAL =0X00;       
}
void TickDelayMs(u16 nms)
{        
u32 temp;    
SysTick->LOAD=nms*fac_ms -1;
SysTick->VAL =0x00;
SysTick->CTRL=0x01 ;
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16)));
SysTick->CTRL=0x00;
SysTick->VAL =0X00;  
}

 

中断方式延时使用步骤

1)配置SysTick定时器时钟源

2)调用系统函数SysTick_Config(),开启中断,配置中断间隔

3)延时函数赋值延时变量,并等待延时变量递减到0,达到精确延时效果

4)中断函数中延时变量递减到0 相关函数如下:

 

__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
   if ((ticks - 1) > 0xFFFFFF)//24位寄存器,大于该值返回错误
   {
      return (1);  
   }
  SysTick->LOAD  = (uint32_t)(ticks - 1);//计数到0,ticks值应减1   
  NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1);
  SysTick->VAL   = 0UL;    
  SysTick->CTRL  = (1<<2) |(1<<1) | 1;//配置时钟源,使能定时器,开启中断
  return (0UL);  
}
void TickInterruptDelay(__IO u32 nTime)
{
  TimingDelay = nTime;
  while(TimingDelay != 0);
}
void TickInterruptHandleTimingDelay_Decrement(void)
{
  if (TimingDelay != 0)
   {
     TimingDelay--;
   }
}

 

测量短时函数的执行时间

SysTick计时器可用于计时测量。例如,可以使用以下代码测量短函数的持续时间:

SysTick->CTRL = 0; // 禁用 SysTick

SysTick->LOAD = 0xFFFFFFFF; // 设置重装寄存器到最大值

SysTick->VAL = 0; // 清零VAL

SysTick->CTRL = 0x5; // 使能SysTick, 使用处理器时钟

while(SysTick->VAL != 0); // 等待重装完毕

start_time = SysTick->VAL; // 较大的起始点

TestDelayFunc(); // 待测函数执行时间

stop_time = SysTick->VAL; // 获取执行结束时间

cycle_count = start_time e stop_time;//计算函数执行时间

由于SysTick是一个递减计数器,因此start_time的值大于stop_time。如果待测函数执行时间较长,这种情况必须启用SysTick异常,并使用SysTick处理程序来计算SysTick计数器下溢的次数。

总结及注意事项

SysTick定时器是微处理器系统内部定时器,提供精确的时间延时和计时功能。采用中断方式延时,需要考虑SysTick中断优先级较低,容易被打断影响延时;在嵌入式系统中,系统将使用SysTick计时器,应用程序中则不可在使用SysTick;在系统在线调试停止时,SysTick计时器将停止计时。

审核编辑:汤梓红

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分