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 的中断。
版权属于:编码书生
本文链接:https://codess.cc/archives/12.html
所有原创文章采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可。
除特别注明,您可以自由的转载和修改,但请务必注明文章来源且不可用于商业目的。