首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

不占用定时器进行精确延时

不占用定时器进行精确延时

研究了一下CM3手册,其中有这么一部分:
也就是说调试组件带有一个对CPU时钟进行计数的功能,可以利用它进行延时。代码如下:

#define  DWT_CR      *(volatile u32 *)0xE0001000
#define  DWT_CYCCNT  *(volatile u32 *)0xE0001004
#define  DEM_CR      *(volatile u32 *)0xE000EDFC
#define  DBGMCU_CR   *(volatile u32 *)0xE0042004
#define  DEM_CR_TRCENA                   (1 << 24)
#define  DWT_CR_CYCCNTENA                (1 <<  0)

#define Delayms(msec)         Delayus(msec*1000)  //对于延时毫秒级的只需要定义一个宏

static u32 cpuclkfeq;     //用于保存cpu运行频率,可运行时动态修

//初始化延时系统,参数为CPU频率
void DelayInit(u32 clk)

{
    cpuclkfeq = clk;

//打开CYCCNT功能
    DEM_CR         |=  DEM_CR_TRCENA;

}

//延时函数,参数为需要延时的微秒数
void Delayus(u32 usec)
{
     u32 ts;
    //先关闭cpu时钟计数器,并把计数器清零,最后打开计数器对cpu时钟进行向上计数

    DWT_CR         &= ~DWT_CR_CYCCNTENA;
    DWT_CYCCNT      = 0u;
    DWT_CR         |= DWT_CR_CYCCNTENA;
     ts =  usec * (cpuclkfeq /(1000*1000) );        //计算达到所需延时值的cpu时钟数,^-^如果想要更精确此处可以减去运行前面代码所需的时钟数。

      while(DWT_CYCCNT < ts);        //等到计数到所需延时值的cpu时钟数
}



在应用时先调用 DelayInit初始化,然后就可以调用Delayus,Delayms进行延时了。

实际应用中效果很好,很精确并且不占用其他资源在跑OS尤其适用。
返回列表