DWT硬件延时
文章目录
- DWT硬件延时
- 软件&硬件延时方案
- 软件延时
- 硬件延时方案
- DWT硬件延时方案
- DWT硬件延时方案
- DEMCR寄存器
- DWT硬件延时方案实现
- 延时初始化:
- US延时:
- MS延时:
软件&硬件延时方案
软件延时
static void Delay(uint32_t count){
while (count--);
}
软件延时的缺点:
-
延时精度差;
-
受系统主频影响,调校困难。
硬件延时方案
硬件延时,利用计数功能的硬件进行延时,比如单片机片上定时器(Timer) ,内核滴答定时器(systick)等:
void SysTick_Handler(void){
HAL_IncTick();
}
__weak void HAL_IncTick(void){
uwTick++;
}
__weak void HAL_Delay(_IO uint32_t Delay){
uint32_t tickstart = 0;
tickstart = HAL_GetTick();
while((HAL_GetTick() - tickstart) < Delay);
}
__weak uint32_t HAL_GetTick(void){
return uwTick;
}
DWT硬件延时方案
Cortex-M4内核架构图
DWT硬件延时方案
- DWT里有一个32位的寄存器叫CYCCNT,它是一个向上计数器,记录的是内核时钟运行的次数,内核时钟跳动一次,该计数器就加1,如果内核时钟是120MHz,那精度就是1/120M = 8.3ns,而单片机程序的运行时间通常都是微秒级别的,所以DWT实现延时的精度是非常高的。
- 要实现DWT延时的功能,总共涉及到三个内核寄存器: DEMCR、 DWT_CTRL、 DWT_CYCCNT,分别用于开启DWT功能、开启CYCCNT及获得系统时钟计数值;当CYCCNT溢出之后,会清O重新开始向上计数。
- 如果内核时钟是120MHz,直接使用CYCCNT延时最大值为: 232*1/120M = 36S
DEMCR寄存器
使能DWT,需要向DEMCR寄存器的24位写1,寄存器定义位于core_cm4.h:
CoreDebug->DEMCR &=
~CoreDebug_DEMCR_TRCENA_Msk;
CoreDebug->DEMCR |=
CoreDebug_DEMCR_TRCENA_Msk;
DWT硬件延时方案实现
使能计数器,需要向CTRL寄存器的0位写1:
DWT->CTRL &= ~DWT_CTRL_CYCCNTENA_Msk;
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
计数器清零:
DWT->CYCCNT = 0;
延时初始化:
/*
@brief DWT初始化配置
*
@param
@return
*/
void Delaylnit(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;
}
US延时:
/*
@brief 微秒级延时函数
@param nUs,最大延时时间( 2^32 /内核主频)*10^6 us
@return
*/
void DelayNus(uint32_t nUs){
uint32_t tickStart = DWT->CYCCNT;
/*转换为nUs对应的时钟跳动次数*/
nUs *= (rcu_clock_freq_get(CK_AHB) / 1000000);
/* 延时等待 */
while ((DWT->CYCCNT - tickStart) < nUs);
}
MS延时:
/*
@brief 毫秒级延时函数
@param nMs,延时时间n毫秒
*
@return
*/
void DelayNms(uint32_t nMs){
for (uint32_ti = 0; i < nMs; i++){
DelayNus(1000);
}
}