###来源于 B站up主 竞赛窖头。

##以及知乎博主

DWT可以实现延时功能,因为它有一个32的计数器CYCCNT,这是一个向上计数的计数器,当它溢出时会自动清零并重新开始向上计数,它的频率就是内核的主频。简单点说,就是内核时钟跳动一下,CYCCNT计数器就加1。

(所以,我们要操作它的寄存器 CYCCNT)

STM32cubemx配置如下:

然后,我们还需要更改一下时钟树的配置。

 

好了,以上就是在cubemx的所有需要更改的配置。

小提示: DWT这个外设,你是无法在Cubemx里面找到对应的位置。因为它是隐藏起来的。为什么博主知道这个外设呢? 因为之前进机器人战队的时候,考核内容里有要求使用DWT 来统计各个函数的耗时。 因为机器人的每一步都需要快速响应,所以我们得找到可以精确统计时间的外设,也就是DWT了。 

使能DWT:

可以看到,我正在main.c文件中来初始化该外设。

  /*
1.先使能DWT外设,由内核调试寄存器DWT_CR的位24控制,写1使能

2.使能CYCCNT寄存器之前,先清0

3.使能CYCNNT寄存器,由DWT_CTRL的位0控制,写1使能
  */
  //DWT初始化
  CoreDebug->DEMCR |= 1 << 24 ;    //使能DWT外设
  DWT->CYCCNT       = 0;           //清零CYCCNT
  DWT->CTRL        |= 1 << 0;     //使能计数
  

1.先使能DWT外设,由内核调试寄存器DWT_CR的位24控制,写1使能

2.使能CYCCNT寄存器之前,先清0

3.使能CYCNNT寄存器,由DWT_CTRL的位0控制,写1使能

对于 那个CoreDebug 可能只针对 Coretx-M3 系列的芯片。(只有 Coretx-M3以及以上的系列的芯片才有这个外设。)

2.使用 DWT来 计算耗时。



// 计算计数差值  只是用来计算  不能超过最大测量时间 59秒
uint32_t getDWTCountDx(uint32_t startTick, uint32_t stopTick)
{
	uint32_t tick;
	if(stopTick < startTick)
	{
		tick = (0xffffffff - startTick) + stopTick + 1;
	}
	else
	{
		tick = stopTick - startTick;
	}
	
	return tick;
}




/*
回调函数 里面使用的是 DWT外设 只有Cortex-3 以及以上才有这个外设
优点: 测量十分精确
缺点: 不能产生中断

这里的 第一次测量是错误值,但是之后的测量是正确的。
上一次的结束值 为 下一次的起始值
*/

// 注意: 回调函数是再中断程序内执行,不能在这个函数里面执行耗时操作
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  static uint32_t startTick = 0,stopTick,tick;	 //必须是静态变量
	// 一定是静态变量 来记录初值
  /* Prevent unused argument(s) compilation warning */
  UNUSED(GPIO_Pin);
 //本人的板子就只有两个按键 所以只设置两个sw
	switch(GPIO_Pin)
	{
		case sw1_Pin:
					if(HAL_GPIO_ReadPin(sw1_GPIO_Port,sw1_Pin) == GPIO_PIN_RESET)
					{
						stopTick = DWT->CYCCNT;
						
						tick = getDWTCountDx(startTick,stopTick);
						if(tick > 720000) // 10ms
						  WS_Debug("SW1 down time is %.2fms\r\n",(float)tick/72000);
						
						startTick = stopTick;
					}
					break;
		
		case sw2_Pin:
					if(HAL_GPIO_ReadPin(sw2_GPIO_Port,sw2_Pin) == GPIO_PIN_RESET)
					{
						stopTick = DWT->CYCCNT;
						
						tick = getDWTCountDx(startTick,stopTick);
						if(tick > 72000) // 10ms
						  WS_Debug("SW2 down time is %.2fms\r\n",(float)tick/72000);
						
						startTick = stopTick;
					}	
					break;
					
	//  case sw3_pin:
	}
	
}

1.对于 getDWTCountDx() 这个函数只是我们用来计算时间, 并且它的最大测量时间是 59秒。超过59秒的不能使用这个函数了。

2.接下来的switch()中的 判断中的逻辑, 第一次的统计并不准确;以后的测量值都为准确值。我们以上一次的终止时间为 下一次的开始时间。

tick 用来承接getDWTCountDx()的结果,它是以us(微秒)单位。 因为我们的使用的是72MHZ的频率。 所以结果 / 72000 — 所得结果为 ms(毫秒) 

if(tick > 72000) // 就是把它看作作为 10ms来使用    7200 是 1ms  72000 是 10ms 

这个用来模拟抖动处理,我们统计的更加精确了。

————————————————————————-

以上,就是我对于 DWT的使用 和 原理的基本认识

DWT
优点: 测量十分精确
缺点: 不能产生中断

所以大家需要根据实际情况来使用DWT外设。

作者:MADAO_luv

物联沃分享整理
物联沃-IOTWORD物联网 » STM32的隐藏定时器—DWT

发表回复