STM32之使用DWT外设编写延时函数
2026/7/10 21:47:17 网站建设 项目流程

T 是一个调试外设,它的核心功能之一是 CYCCNT(Cycle Count),这是一个32位递增计数器,用于记录 CPU 执行的时钟周期数量。我们可以通过对这个计数器的变化来实现高精度延时。

在使用 DWT 延时之前,需要完成以下操作:

使能 DWT

使能 CYCCNT

清零 CYCCNT

基于 CYCCNT 实现延时逻辑

源码如下:

dwt.delay.h文件

#ifndef __DWT_DELAY_H

#define __DWT_DELAY_H

#include "stm32g4xx.h"

/* 获取内核时钟频率 */

#define GET_CPU_ClkFreq() HAL_RCC_GetSysClockFreq()

uint32_t CPU_TS_TmrRd(void);

HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority);

//最大延时值为8秒

void dwt_delay_us(uint32_t us);

#define HAL_Delay(ms) dwt_delay_us(ms*1000)

#define dwt_delay_s(s) dwt_delay_us(s*1000000)

#endif /* __DWT_DELAY_H */

dwt_delay.c文件

#include "dwt_delay.h"

#define DWT_CR *(__IO uint32_t *)0xE0001000

#define DWT_CYCCNT *(__IO uint32_t *)0xE0001004

#define DEM_CR *(__IO uint32_t *)0xE000EDFC

#define DEM_CR_TRCENA (1 << 24)

#define DWT_CR_CYCCNTENA (1 << 0)

/**

* @brief 初始化时间戳

* @param 无

* @retval 无

* @note 使用延时函数前,必须调用本函数

*/

HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)

{

/* 使能DWT外设 */

DEM_CR |= (uint32_t)DEM_CR_TRCENA;

/* DWT CYCCNT寄存器计数清0 */

DWT_CYCCNT = (uint32_t)0u;

/* 使能Cortex-M DWT CYCCNT寄存器 */

DWT_CR |= (uint32_t)DWT_CR_CYCCNTENA;

return HAL_OK;

}

/**

* @brief 读取当前时间戳,每1ms更新一次

* @param 无

* @retval ms时间戳

*/

uint32_t HAL_GetTick(void)

{

return ((uint32_t)DWT_CYCCNT/(GET_CPU_ClkFreq()*1000));

}

/**

* @brief 采用CPU的内部计数实现精确延时,32位计数器,最大延时时间8秒

* @param us : 延迟长度,单位1 us

* @retval 无

*/

void dwt_delay_us(uint32_t us)

{

uint32_t ticks;

uint32_t told,tnow,tcnt=0;

ticks = us * (GET_CPU_ClkFreq() / 1000000); /* 需要的节拍数 */

tcnt = 0;

told = (uint32_t)DWT_CYCCNT; /* 刚进入时的计数器值 */

while(1)

{

tnow = (uint32_t)DWT_CYCCNT;

if(tnow != told)

{

if(tnow > told)

{

tcnt += tnow - told;

}

else /* 重新装载 */

{

tcnt += UINT32_MAX - told + tnow;

}

told = tnow;

/*时间超过/等于要延迟的时间,则退出 */

if(tcnt >= ticks)break;

}

}

}

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询