本帖最后由 发条陈 于 2022-7-24 02:39 编辑
#技术资源#
Cortex M3/4隐藏的定时器 -- DWT
1、关于DWT
在Cortex-M3/4中除了处理器内核外还有很多组件,其中包括调试仿真的组件,里面有一个外设叫DWT(Data Watchpoint and Trace),是用于系 统调试及跟踪。
由此可见,寄存器CYCCNT,它是一个向上的计数器,记录的是内核时钟运行的个数,内核时钟跳动一次,该计数器就加1,精度非常高,决定内核的频率是多少,如果是F103系列,内核时钟是72M,那精度就是1/72M = 14ns,而程序的运行时间都是微秒级别的,所以14ns的精度是远远够的。最长能记录的时间为:60s=2的32次方/72000000(假设内核频率为72M,内核跳一次的时间大概为1/72M=14ns)。当CYCCNT溢出之后,会清0重新开始向上计数。
2、相关寄存器
DEMCR
想要使能DWT外设,需要由另外的内核调试寄存器DEMCR的位24控制,写1使能。
DEMCR的地址是0xE000 EDFC。
DWT_CYCCNT
让我们看看DWT_CYCCNT的基地址,从ARM-Cortex-M手册中可以看到其基地址是0xE000 1004,复位默认值是0,而且它的类型是可读可写的,我们往0xE000 1004这个地址写0就将DWT_CYCCNT清0了。
CYCCNTENA
CYCCNTENA使能CYCCNT计数器。如果未启用,计数器不会计数,并且不会为PS采样或CYCCNTENA生成事件。在正常使用中,调试器必须将CYCCNT计数器初始化为0。
3、实例(AMP32E103)
要实现延时的功能,总共涉及到三个寄存器:DEMCR 、DWT_CTRL、DWT_CYCCNT,分别用于开启DWT功能、开启CYCCNT及获得系统时钟计数值。
1)获取当前系统的时钟,计算时间片
void dwt_delay_init()
{
uint32_t sysclkfreq;
/* get system clock */
sysclkfreq = RCM_ReadSYSCLKFreq();
/* configure dwt */
dwt_fac_us = sysclkfreq / (1000000U);
dwt_fac_ms = dwt_fac_us * (1000U);
}
实现延时xx us的函数
void dwt_delay_us(uint32_t nus)
{
/* Enable CoreDebug DEMCR bit24: TRCENA */
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
/* Clear CYCCNT */
DWT->CYCCNT = 0x00;
/* Enable DWT CTRL bit0: CYCCNTENA */
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
uint32_t temp = DWT->CYCCNT;
while((DWT->CYCCNT - temp) < nus * dwt_fac_us);
/* Disable DWT CTRL bit0: CYCCNTENA */
DWT->CTRL &= ~DWT_CTRL_CYCCNTENA_Msk;
/* Clear CYCCNT */
DWT->CYCCNT = 0x00;
/* Disable CoreDebug DEMCR bit24: TRCENA */
CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk;
}
同理实现延时xx ms的函数
void dwt_delay_ms(uint16_t nms)
{
/* Enable CoreDebug DEMCR bit24: TRCENA */
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
/* Clear CYCCNT */
DWT->CYCCNT = 0x00;
/* Enable DWT CTRL bit0: CYCCNTENA */
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
uint32_t temp = DWT->CYCCNT;
while((DWT->CYCCNT - temp) < nms * dwt_fac_ms);
/* Disable DWT CTRL bit0: CYCCNTENA */
DWT->CTRL &= ~DWT_CTRL_CYCCNTENA_Msk;
/* Clear CYCCNT */
DWT->CYCCNT = 0x00;
/* Disable CoreDebug DEMCR bit24: TRCENA */
CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk;
}
实测IO翻转波形
|