本课将为大家讲解CKS32F4xx系列产品的SysTick定时器原理及使用方法。SysTick定时器也叫SysTick滴答定时器,属于Cortex-M4内核外设。SysTick定时器可以用于查询延时、中断延时以及测量函数运行时间;在实时操作系统RTOS中作为滴答定时器,用于上下文切换。采用Cortex-M内核的微处理都有SysTick定时器,方便不同处理器之间的软件移植。SysTick定时器时钟源可直接选取系统时钟,还可以通过系统时钟8分频后取得。
SysTick定时器内部是一个递减的计时器,当减到0时,将从LOAD寄存器中自动重装定时器初始值,重新向下递减计数,如此循环往复。如果开启SysTick中断,当计数器减到0时,SysTick可以生产异常,异常编号为15。
SysTick定时器寄存器
SysTick定时器内部是一个24位向下递减的计时器,包含4个寄存器,如图。
图1 SysTick定时器框图
1)STK_CTRL寄存器
STK_CTRL是SysTick定时器的控制及状态寄存器,相应功能如下:
2) STK_LOAD寄存器
STK_LOAD寄存器是SysTick定时器的重装载数值寄存器,相应功能如下:
3)STK_VAL寄存器
STK_VAL寄存器是SysTick定时器的当前数值寄存器,相应功能如下:
4)STK_CALIB寄存器
STK_CALIB寄存器是SysTick定时器的校准数值定时器,用于利用片上硬件为软件提供校准信息,但使用情况较少。在CMSIS Core中,不需要使用SysTick校准寄存器,因为CMSIS Core提供了一个名为“SystemCoreClock”的软件变量。此变量在系统初始化函数“SystemInit()”中设置,每次更改系统时钟配置时也会更新。这种方法比使用SysTick CalibrationRegister的硬件方法灵活。校准寄存器描述如下表:
查询延时使用步骤
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计时器将停止计时。
审核编辑:汤梓红
全部0条评论
快来发表一下你的评论吧 !