QQ截图1859.png

delay(n)的缺陷

  在进行STM32开发时,经常会遇到软件中需要延时一段时间的情况,大多数开发者会写一个延时函数delay(n)(可能是写51写惯了) n表示需要延时的之间,一般以毫秒位单位。比如:

for(i=0;i<=n;i++)

  此处的n表示需要延时的之间。但是对于STM32来说,系统执行一条指令的时间仅有几十个ns,使用for循环来实现毫秒级的软件延时,此处的n会非常大,而大多数开发者确定n 的方法都是采用编辑器的软件仿真的方法,此方法有一定的缺陷,就是很难精确地计算出延时n毫秒地精确值。


SysTick的好处

  所以针对这种情况,建议采用内核中的SysTick时钟,也叫系统滴答定时器。它属于向量中断控制器(NVIC)的一部分,SysTick是一个24位递减计数器,设定初值并使能之后每经过一个系统始终周期,计数值减1,到 0 时自动重载初值重新递减计数,同时COUNTFLAG标志位置位,触发中断(SysTick异常,异常号:15)。

思路

  使用SysTick作为定时时钟,并设定每1毫秒产生一次中断,并且再中断处理函数中对n进行减一,而delay(n)函数中检测n是否为0,若n为0,则关闭SysTick系统滴答时钟。并且,非常重要的一点:延时时间不会随着系统时钟频率的变化而改变,因为Cortex-M3内核的滴答频率不会随着外部时钟频率的变化而改变。

示例:

//  初始化重载值,中断使能
SysTick_SetReload(9000);   //设定SysTick 1 ms 计数值
SysTick_ITConfig(ENABLE)   //使能SysTick中断;

//  中断处理函数;
 void SysTick_Interrupt(void){

    if (Timedelay !=0x00)   Timedelay--;
}

//  延时代码;
void delay(u32 n){
    SysTick_Count_Cmd(SysTick_Counter_Enable);   //使能SysTick计数器;
    Timedelay = n;                               //读取延时时间;
    while(Timedelay != 0);                       //判断延时;
    SysTick_CounterCmd(SysTick_Counter_Disable); //关闭SysTick计数器;
    SysTick_CounterCmd(SysTick_Counter_Clear);   //清除SysTick计数器
}

//  示例应用

delay(10)    //延时10ms

注意:以上代码的条件为:外部晶振8MHz,系统时钟72MHz,SysTick的频率为9MHz,由系统滴答定时器SysTick产生 1ms 的中断。

最后修改:2019 年 09 月 20 日
您的支持就是我持续更新的动力!