STM32 DWT数据观察触发器作为延时函数的使用

STM32 DWT数据观察触发器作为延时函数的使用


📑DWT(Data Watchpoint and Trace数据观察触发器)描述

  • 📝DWT是属于处理器内核单元中的调试组件之一,由四个比较器组成。它们可配置为:硬件监视点或对ETM或PC采样器或数据地址采样器的触发器。DWT还提供了一些方法来提供一些分析信息。为此,可以访问一些计数器来提供:时钟循环折叠指令加载存储单元(LSU)操作休眠周期CPI(每个指令的时钟)中断开销。
  • 🔖DWT似乎除了M0内核的没有其他的都有。具体型号有没有,请参考对应的内核参考手册。在数据手册上没有此相关信息。
  • 🔖以下内容引自野火开发文档描述:https://doc.embedfire.com/mcu/stm32/f103badao/std/zh/latest/book/DWT.html
  • 🌿在Cortex-M中,DWT是用于系统调试及跟踪,它有一个32位的寄存器叫CYCCNT, 它是一个向上的计数器,记录的是内核时钟运行的个数,内核时钟跳动一次,该计数器就加1,精度非常高,决定内核的频率是多少, 对于F103系列,内核时钟是72M,那精度就是1/72M = 14ns,而程序的运行时间都是微秒级别的,所以14ns的精度是远远够的。 最长能记录的时间为:60s=2的32次方/72000000(假设内核频率为72M,内核跳一次的时间大概为1/72M=14ns), 而如果是H7这种400M主频的芯片,那它的计时精度高达2.5ns(1/400000000 = 2.5),而如果是 i.MX RT1052这种高速的处理器, 最长能记录的时间为: 8.13s=2的32次方/528000000 (假设内核频率为528M,内核跳一次的时间大概为1/528M=1.9ns) 。当CYCCNT溢出之后, 会清0重新开始向上计数。系统处理框图见图:

在这里插入图片描述
要实现延时的功能,总共涉及到三个寄存器:DEMCR、DWT_CTRL、DWT_CYCCNT,分别用于开启DWT功能、开启CYCCNT及获得系统时钟计数值。

📘DWT相关寄存器

  • 🌿DEMCR
    想要使能DWT外设,需要由另外的内核调试寄存器DEMCR的位24控制,写1使能。DEMCR的地址是:0xE000EDFC
    在这里插入图片描述
  • 🌿DWT_CYCCNT
    使能DWT_CYCCNT寄存器之前,先清0。其基地址是0xE0001004,复位默认值是0,可读写类型。所以往0xE0001004这个地址写就将DWT_CYCCNT清0了。
  • 🌿CYCCNTENA
    它是DWT控制寄存器的第一位,写1使能,则启用CYCCNT计数器,否则CYCCNT计数器将不会工作。
    在这里插入图片描述
  • 🧨综上所述,想要使用DWT的CYCCNT需要以下3个步骤:
  1. 先使能DWT外设,这个由另外内核调试寄存器DEMCR的位24控制,写1使能。
  2. 使能CYCCNT寄存器之前,先清0。
  3. 使能CYCCNT寄存器,这个由DWT的CYCCNTENA 控制,也就是DWT控制寄存器的位0控制,写1使能。

📗DWT当定时器使用

  • 🌿初始化寄存器
/**
* @brief  初始化时间戳
* @param  无
* @retval 无
* @note   使用延时函数前,必须调用本函数
*/
void CPU_TS_TmrInit(void)
{
    /* 使能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;
}
  • 🌿延时函数
/**
* @brief  采用CPU的内部计数实现精确延时,32位计数器
* @param  us : 延迟长度,单位1 us
* @retval 无
* @note   使用本函数前必须先调用CPU_TS_TmrInit函数使能计数器,
            或使能宏CPU_TS_INIT_IN_DELAY_FUNCTION
            最大延时值为60秒,即60s=2的32次方/72000000
*/
void CPU_TS_Tmr_Delay_US(__IO uint32_t us)
{
    uint32_t ticks;
    uint32_t told,tnow,tcnt=0;

    /* 在函数内部初始化时间戳寄存器, */
#if (CPU_TS_INIT_IN_DELAY_FUNCTION)
    /* 初始化时间戳并清零 */
    CPU_TS_TmrInit();
#endif

    ticks = us * (GET_CPU_ClkFreq() / 1000000);  /* 需要的节拍数 */
    tcnt = 0;
    told = (uint32_t)CPU_TS_TmrRd();         /* 刚进入时的计数器值 */

    while (1) {
        tnow = (uint32_t)CPU_TS_TmrRd();
        if (tnow != told) {
            /* 32位计数器是递增计数器 */
            if (tnow > told) {
                tcnt += tnow - told;
            }
            /* 重新装载 */
            else {
                tcnt += UINT32_MAX - told + tnow;
            }

            told = tnow;

            /*时间超过/等于要延迟的时间,则退出 */
            if (tcnt >= ticks)break;
        }
    }
}

📚测试工程

  • 🔖基于hal stm32f103
链接:https://pan.baidu.com/s/169wTGNecTqwBXqhuYzSVew?pwd=nbx4 
提取码:nbx4
  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值