欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

STM32:使用DWT测量某段程序运行时间

程序员文章站 2022-03-10 21:01:03
...

一、思路

使用DWT进行追踪计数,在需要测试的程序段前后,设置(全局)volatile 变量读取DWT的计数值。然后将前后数值相减,就得到了这一段程序运行所需要的节拍数,然后在将节拍数除以时钟频率(若时钟频率为72M,则除以72 000 000,以此类推),就得到了这一段程序运行所需要的时间。

二、DWT的初始化与使用方法

1、有关DWT用作延时或者用于计数用途,在网上有很多资料,可自行查询。这里直接使用一段网上的相关代码:

#include "DWTDelay.h"
 
// 0xE000EDFC DEMCR RW Debug Exception and Monitor Control Register.
#define DEMCR           ( *(unsigned int *)0xE000EDFC )
#define TRCENA          ( 0x01 << 24) // DEMCR的DWT使能位
 
// 0xE0001000 DWT_CTRL RW The Debug Watchpoint and Trace (DWT) unit
#define DWT_CTRL        ( *(unsigned int *)0xE0001000 )
#define CYCCNTENA       ( 0x01 << 0 ) // DWT的SYCCNT使能位
// 0xE0001004 DWT_CYCCNT RW Cycle Count register, 
#define DWT_CYCCNT      ( *(unsigned int *)0xE0001004) // 显示或设置处理器的周期计数值
 
//#define DWT_DELAY_mS(mSec)    DWT_DELAY_uS(mSec*1000)
 
static int SYSCLK = 0;;
 
void DWT_INIT(int sys_clk)
{
  DEMCR |= TRCENA;
  DWT_CTRL |= CYCCNTENA;
  
  SYSCLK = sys_clk; // 保存当前系统的时钟周期,eg. 72,000,000(72MHz). 
}
 
// 微秒延时
void DWT_DELAY_uS(int uSec)
{
  int ticks_start, ticks_end, ticks_delay;
  
  ticks_start = DWT_CYCCNT;
  
  if ( !SYSCLK )
    DWT_INIT( MY_MCU_SYSCLK );
  
  ticks_delay = ( uSec * ( SYSCLK / (1000*1000) ) ); // 将微秒数换算成滴答数          
  
  ticks_end = ticks_start + ticks_delay;
  
  if ( ticks_end > ticks_start )
  {
    while( DWT_CYCCNT < ticks_end );
  }
  else // 计数溢出,翻转
  {
    while( DWT_CYCCNT >= ticks_end ); // 翻转后的值不会比ticks_end小
    while( DWT_CYCCNT < ticks_end );
  }
}

2、大致使用方法如图所示:

STM32:使用DWT测量某段程序运行时间

注:若出现 start  >  end , 则表示DWT计数寄存器已经溢出,然后进行翻转重新计数。由于DWT为32位寄存器,即最大计数值为2^32  - 1 , 需要自行计算一下总的计数值:(2^32 - 1) -  start  + end 。