????????从原理上来说,Systick定时器和开发板上的通用定时器没有区别。从功能上来说,Systick定时器主要是用来用来进行延时的,而通用或者高级定时器往往用来进行PWM输出、输入捕获等功能。至于为什么不用通用定时器或者高级定时器来完成延时功能,则是考虑到节省MCU的资源来做更重要的事。
void systick_config(void)
{
/* setup systick timer for 1000Hz interrupts */
if (SysTick_Config(SystemCoreClock / 1000U)){
/* capture error */
while (1){
}
}
/* configure the systick handler priority */
NVIC_SetPriority(SysTick_IRQn, 0x00U);
}
?SysTick_Config的参数,其实就是一个时钟次数,叫systick重装定时器的值。已知预装载值和时钟频率,那么可以求出进入一次中断的时间
预装载值/时钟频率
(SystemCoreClock / 1000U)/ (SystemCoreClock) S 进入一次中断,也就是1ms进入一次
void delay_1ms(uint32_t count)
{
delay = count;
while(0U != delay){
}
}
void delay_decrement(void)
{
if (0U != delay){
delay--;
}
}
void SysTick_Handler(void)
{
delay_decrement();
}
void delay_1ms(uint32_t count)
{
uint32_t ticks;
uint32_t told,tnow,reload,tcnt=0;
reload = SysTick->LOAD; //获取重装载寄存器值
ticks = count * (SystemCoreClock / 1000); //计算定时1ms滴答定时器要计数的时间值
told=SysTick->VAL; //获取当前数值寄存器值
while(1)
{
tnow = SysTick->VAL; //获取当前数值寄存器值
if(tnow!=told) //当前值不等于开始值说明已在计数。切记:滴答定时器是倒计数
{
if(tnow<told) //当前值小于开始数值,说明未计到0
tcnt += told - tnow; //计数值=开始值-当前值
else //当前值大于开始数值,说明已计到0并重新计数
tcnt += reload-( tnow - told ); //told tnow reload (相当于整段事件中只有told到tnow这段时间没有计时
told = tnow; //更新开始值
if(tcnt >= ticks)break; //计数值大于等于要延迟的计数值,则计数完毕
}
}
}