STM32的隐藏定时器---DWT
###来源于 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寄存器之前,先清03.使能CYCNNT寄存器,由DWT_CTRL的位0控制,写1使能*///DWT初始化CoreDebug->DEMCR |= 1 << 24 ; //使能DWT外设DWT->CYCCNT = 0; //清零CYCCNTDWT->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);//本人的板子就只有两个按键 所以只设置两个swswitch(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) // 10msWS_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) // 10msWS_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外设。