下面是一个传统的延时函数的通用做法:
这种延时做法有几个缺点:
-
参数n要调试,比如传入1是1US,传入10不一定得10US
-
在使用这个延时得时候要关闭中断,否则有可能延时会变长
-
不同的编译环境、优化等级都有可能对这个延时的时间有影响
为了解决这些问题,这里使用Systemtick来做延时,使用方法如下: -
在需要的地方提前初始化并开始延时机制:
-
在需要延时的地方调用延时函数:
Systemtick的延时函数因为VAL的值的递减是由硬件控制的所以时间很好算也很准。再因为VAL值是由硬件减的,所以及时中途被中断打断了,只要打断的时间不是很长这个延时依旧不会偏差。因为延时是硬件递减的,所以不会受编译器和忧患等级的影响!
请从如下地址下载:https://download.csdn.net/download/chengdong1314/20102218
改良版
上面说到的延时机制只能够算是一个思路,局限性太小了,这里专门做了一套兼容SDK的延时函数,具体代码如下:
/*
延时函数文件
作者:北京盛源达科技有限公司
日期:2016/7/8
*/
#include "delay.h"
#include "DebugLog.h"
#define DELAY_DEBUG
volatile uint32_t tick_total=0,tick_first=0;
uint8_t sysTick_irq=0;
void SysTick_Handler(void)
{
sysTick_irq=1;
}
void SysTick_polling(void)
{
if(sysTick_irq==1)
{
sysTick_irq=0;
if(tick_first)
{
tick_total-=tick_first;
tick_first=0;
#ifdef DELAY_DEBUG
dbg_printf("tick_first:%d\r\n",tick_total);
#endif
}
else
{
if(tick_total>=0xFFFFFF) tick_total-=0xFFFFFF;
#ifdef DELAY_DEBUG
dbg_printf("tick_second:%d\r\n",tick_total);
#endif
}
}
}
/*
n毫秒延时函数
参数: uint16_t n 要延时的毫秒数 单位:1ms
*/
void delay_ms(uint32_t n){
tick_first=SysTick->VAL;
tick_total=n*64*1000;
if(tick_first>=tick_total)
{
#ifdef DELAY_DEBUG
dbg_printf("first:%d %d\r\n",n,tick_first);
#endif
while(tick_total>(tick_first-SysTick->VAL)) SysTick_polling();
}
else
{
#ifdef DELAY_DEBUG
dbg_printf("second:%d %d\r\n",n,tick_first);
#endif
while((tick_first!=0)||(tick_total>(0xFFFFFF-SysTick->VAL))) SysTick_polling();
}
tick_total=0;
#ifdef DELAY_DEBUG
dbg_printf("end:%d\r\n",SysTick->VAL);
#endif
}
开机的时候按照如下方式初始化:
SysTick_Config(0xFFFFFF); //最大值
这时候得到的35ms非常准确:
本章节内容可以从如下地址下载:https://download.csdn.net/download/chengdong1314/87537987