cubemx生成的工程中再主函数的页面都会有void SystemClock_Config(void)函数,这个函数我们今天只看有关于systic的部分。
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
在这个函数里这三句是关于滴答定时器的。
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
{
return (1UL); /* Reload value impossible */
}
SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0UL); /* Function successful */
}
我们就先看这个第一句代码,参数里面还有一个函数,是返回HCLK的频率,传入的参数就是HCLK/1000=72000(72Mhz,72000个脉冲就是1ms)
然后看接着看函数,函数里面首先是判断传入的值是否超过了允许的值,因为在寄存器中,自动重装载值占用了24位。剩下的8位是保留位。
下面就是配置了。先是配置自动重装载寄存器的值,然后是为滴答定时器中断分配了抢占优先级。后面是为当前计数值寄存器赋值,最后是配置CTRL寄存器第三位,使能计数,中断,时钟选择AHB
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);这个函数是配置systic的时钟源,上面已经选了HCLK作为时钟源,这里也是一样,有点重复。
最后就是配置了下systic的NVIC了。
分析一下这些配置,
选择了时钟,
设置了中断抢占优先级。
当前计数器
自动重装载计数器
开启中断
总结一下就是给了它时钟源,让当前计数值寄存器按一定频率倒计时,当到达0时,触发中断,并且将自动重装载的值放入当前计数值寄存器。
说明一下自动重装载值可以赋值0,但是没有影响,只有从1到0的时候才会触发中断和count_flag。
校准值寄存器提供了这样一个解决方案:它使系统即使在不同的 CM3 产品上运行,也能产生恒定的SysTick 中断频率。最简单的作法就是:直接把 TENMS 的值写入重装载寄存器,这样一来,只要没突破系统的“弹性极限”,就能做到每 10ms 来一次 SysTick 异常。如果需要其它的 SysTick 异常周期,则可以根据 TENMS 的值加以比例计算。