DWT硬件延时

发布时间:2026/7/4 20:42:43
DWT硬件延时 1、Cortex-M4内核架构2、硬件延时利用计数功能的硬件进行延时比如单片机片上定时器Timer内核滴答定时器(systick)等__weak void HAL_IncTick(void) { uwTick; } __weak uint32_t HAL_GetTick(void) { return uwTick; } void SysTick_Handler(void) { HAL_IncTick(); } __weak void HAL_Delay(__IO uint32_t Delay) { uint32_t tickstart 0; tickstart HAL_GetTick(); while((HAL_GetTick() - tickstart) Delay); }3、DWT监视点单元数据跟踪硬件延时方案DWT里有一个32位的寄存器叫CYCCNT它是一个向上计数器记录的是内核时钟运行的次数内核时钟跳动一次该计数器就加1如果内核时钟是120MHz那精度就是1/120M 8.3ns而单片机程序的运行时间通常都是微秒级别的所以DWT实现延时的精度是非常高的。要实现DWT延时的功能总共涉及到三个内核寄存器DEMCR 、DWT_CTRL、DWT_CYCCNT分别用于开启DWT功能、开启CYCCNT及获得系统时钟计数值当CYCCNT溢出之后会清0重新开始向上计数。如果内核时钟是120MHz直接使用CYCCNT延时最大值为 232 * 1/120M 36S。注DWT只在Cortex-M3及以上内核中存在。①使能DWT需要向DEMCR寄存器的24位写1寄存器定义位于core_cm4.hCoreDebug-DEMCR ~CoreDebug_DEMCR_TRCENA_Msk; /* 关闭 TRC */CoreDebug-DEMCR | CoreDebug_DEMCR_TRCENA_Msk;/* 打开 TRC */②使能计数器需要向CTRL寄存器的0位写1DWT-CTRL ~DWT_CTRL_CYCCNTENA_Msk; /* 关闭计数功能 */DWT-CTRL | DWT_CTRL_CYCCNTENA_Msk;/* 打开计数功能 */③计数器清零DWT-CYCCNT 0;代码编写#include stdint.h #include gd32f30x.h #include delay.h static uint32_t g_sysClock; /** *********************************************************** * brief DWT初始化配置 * param * return *********************************************************** */ void DelayInit(void) { /* 关闭 TRC */ CoreDebug-DEMCR ~CoreDebug_DEMCR_TRCENA_Msk; /* 打开 TRC */ CoreDebug-DEMCR | CoreDebug_DEMCR_TRCENA_Msk; /* 关闭计数功能 */ DWT-CTRL ~DWT_CTRL_CYCCNTENA_Msk; /* 打开计数功能 */ DWT-CTRL | DWT_CTRL_CYCCNTENA_Msk; /* 计数清零 */ DWT-CYCCNT 0; g_sysClock rcu_clock_freq_get(CK_SYS); } /** *********************************************************** * brief 微秒级延时函数 * param nUs最大延时时间( 2^32 / 内核主频 ) * 10^6 us * return *********************************************************** */ void DelayNus(uint32_t nUs) { uint32_t tickStart DWT-CYCCNT; /* 转换为nUs对应的时钟跳动次数*/ nUs * g_sysClock / 1000000; /* 延时等待 */ while ((DWT-CYCCNT - tickStart) nUs); } /** *********************************************************** * brief 毫秒级延时函数 * param nMs延时时间n毫秒 * return *********************************************************** */ void DelayNms(uint32_t nMs) { for (uint32_t i 0; i nMs; i) { DelayNus(1000); } } #ifndef _DELAY_H_ #define _DELAY_H_ #include stdint.h /** *********************************************************** * brief DWT初始化配置 * param * return *********************************************************** */ void DelayInit(void); /** *********************************************************** * brief 微秒级延时函数 * param nUs最大延时时间( 2^32 / 内核主频 ) * 10^6 us * return *********************************************************** */ void DelayNus(uint32_t nUs); /** *********************************************************** * brief 毫秒级延时函数 * param nMs延时时间n毫秒 * return *********************************************************** */ void DelayNms(uint32_t nMs); #endif