关于Systick的理解

概念:

SysTick—系统定时器是属于CM3内核中的一个外设,内嵌在NVIC中。系统定时器是一个24bit的向下递减的计数器,计数器每计数一次的时间为1/SYSCLK,一般我们设置系统时钟SYSCLK等于72M。当重装载数值寄存器的值递减到0的时候,系统定时器就产生一次中断,以此循环往复。

寄存器:

源码分析:

首先,在main函数中的会率先初始化时钟调用HAL_RCC_ClockConfig,在这个函数中,我们主要关注Systick部分,包括更新SystemCoreClock变量,和调用HAL_InitTick配置Systick。这个函数源码如下:

红圈部分函数:HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq))  ,其中SystemCoreClock为HCLK=72MHz,uwTickFreq默认为1,表示1kHz,所以计算得到:HAL_SYSTICK_Config(72000);


HAL_SYSTICK_Config又调用SysTick_Config这个函数。


在SysTick_Config这个函数中,首先会判断预设的Tick是否会溢出,Systick是24位,2的24次方:16777216,预设的Tick需要小于16777216。然后对寄存器继续赋值操作:我们看到SysTick->CTRL的赋值,时钟源是默认是选择AHB,如果要选择AHB8分频,可以通过HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK_DIV8);该函数的源码:


实现一个极简的微妙us延时

//nus = 1~999
void delay_us(uint32_t nus){
  SysTick->VAL = 0X00;    //写操作进行清零
  uint32_t tt = nus * 72;    //1us = 72个计数值
  while(SysTick->VAL == 0 || SysTick->LOAD - SysTick->VAL < tt); 
}

因为SysTick的装载值最大可以是16777216,而我们的默认装载值是经过1000倍缩小的72000,所以装载值具有很大的修改提升空间,我们自然想到通过SysTick->LOAD 来增大装载值,从而提升延时函数的延时最大值,实现ms级别的延时,但是需要谨慎,因为改变装载值,会改变产生一个SysTick中断的时间,从而影响HAL_Delay函数的准确性,我们可能需要重写该函数,另外即使设置装载值为最大,经过计算16777216/72000 约等于233ms,提升不大,

如果结合时钟源分频,即通过HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK_DIV8);设置八分频,那么原来是1ms计72000个数,就变成8ms计72000个数,即1ms即9000个数,计数区间也会提升不少。我们可以计算得到最大延时是:16777216/9000 约等于1864ms,这个值可以在一些场合还是不满足,可以通过for循环进行重复延时来达到更大的延时,或通过时间摘取法实现(这里不展开)。 

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值