一、思路
使用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、大致使用方法如图所示:
注:若出现 start > end , 则表示DWT计数寄存器已经溢出,然后进行翻转重新计数。由于DWT为32位寄存器,即最大计数值为2^32 - 1 , 需要自行计算一下总的计数值:(2^32 - 1) - start + end 。