查看: 3177|回复: 0

[原创] 【野火i.MX RT1052】4.RT1052之内核计数器DWT

[复制链接]
  • TA的每日心情
    擦汗
    2019-6-26 20:59
  • 签到天数: 235 天

    连续签到: 1 天

    [LV.7]常住居民III

    发表于 2018-5-26 11:25:38 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 小马哥-1650185 于 2018-5-26 12:17 编辑

    这一贴文主要来说说rt1052的内核计数器部分

    DWT,全称是The Debug Watchpoint and Trace (DWT) unit,用于系统调试及跟踪,详细的介绍可以参考ARM官方文档:ARMv7-M Architecture Reference Manual


    在Cortex-M里面有一个外设叫DWT(Data Watchpoint and Trace), 该外设有一个32位的寄存器叫CYCCNT,它是一个向上的计数器, 记录的是内核时钟运行的个数,最长能记录的时间为: 8.13s=2的32次方/528000000 (假设内核频率为528M,内核跳一次的时间大概为1/528M=1.9ns) 当CYCCNT溢出之后,会清0重新开始向上计数。

    使能CYCCNT计数的操作步骤:
    1、先使能DWT外设,这个由另外内核调试寄存器DEMCR的位24控制,写1使能
    2、使能CYCCNT寄存器之前,先清0
    3、使能CYCCNT寄存器,这个由DWT_CTRL(代码上宏定义为DWT_CR)的位0控制,写1使能

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


    1. #define  DWT_CR            *(__IO uint32_t *)0xE0001000
    2. #define  DWT_CYCCNT     *(__IO uint32_t *)0xE0001004
    3. #define  DEM_CR            *(__IO uint32_t *)0xE000EDFC
    复制代码
    看手册上 (如下图所示)
    DEM_CR 我们只需要关注其第24位引脚TRCENA,该寄存器的TRCENA位置位,使能DWT功能

    寄存器DWT_CR是控制寄存器  
    DWT_CYCCNT   是循环计数寄存器 我们只开启循环计数功能,当DWT的CYCCNTENA位置位后,该寄存器的值与系统周期计数值保持同步,我们可以用它的值来实现一个延时的功能      
    签名.jpg


    实现代码如下
    1. //寄存器基地址
    2. #define    DWT_CR    *(uint32_t*)0xE0001000
    3. #define    DWT_CYCCNT    *(uint32_t*)0xE0001004
    4. #define    DEM_CR    *(uint32_t*)0xE000EDFC

    5. //定义需使能位
    6. #define    DEM_CR_TRCENA    (1<<24)
    7. #define    DWT_CR_CYCCNTENA    (1<<0)

    8. <blockquote>/**
    复制代码

    采用CPU的内部计数实现精确延时,32位计数器,使用本函数前必须先调用CPU_TS_TmrInit函数使能计数器,  或使能宏CPU_TS_INIT_IN_DELAY_FUNCTION, 最大延时值为8秒,即8*1000*1000

    复制代码
    1. #define  DWT_CR      *(__IO uint32_t *)0xE0001000
    2. #define  DWT_CYCCNT  *(__IO uint32_t *)0xE0001004
    3. #define  DEM_CR      *(__IO uint32_t *)0xE000EDFC


    4. #define  DEM_CR_TRCENA                   (1 << 24)
    5. #define  DWT_CR_CYCCNTENA                (1 <<  0)


    6. /**
    7.   * @brief  初始化时间戳
    8.   * @param  无
    9.   * @retval 无
    10.   * @note   使用延时函数前,必须调用本函数
    11.   */
    12. void CPU_TS_TmrInit(void)
    13. {
    14.     /* 使能DWT外设 */
    15.     DEM_CR |= (uint32_t)DEM_CR_TRCENA;               

    16.     /* DWT CYCCNT寄存器计数清0 */
    17.     DWT_CYCCNT = (uint32_t)0u;

    18.     /* 使能Cortex-M DWT CYCCNT寄存器 */
    19.     DWT_CR |= (uint32_t)DWT_CR_CYCCNTENA;
    20. }


    21. /**
    22.   * @brief  读取当前时间戳
    23.   * @param  无
    24.   * @retval 当前时间戳,即DWT_CYCCNT寄存器的值
    25.   */
    26. uint32_t CPU_TS_TmrRd(void)
    27. {        
    28.   return ((uint32_t)DWT_CYCCNT);
    29. }
    复制代码


    使用函数void CPU_TS_Tmr_Delay_US(uint32_t us)可以实现精确的延时,延时不受代码优化影响。
    例如延时1us
    #define LED_DELAY   CPU_TS_Tmr_Delay_S(1)
    本例程替换前面的延时函数delay(),使用LED_DELAY   达到精确延时。

    在main函数中首先初始化dwt
    1.       //使用时间戳延时函数前必须先使能计数器
    2.       CPU_TS_TmrInit();
    复制代码
    在主循环中实现延时点亮rgb灯
    1.     while(1)
    2.                 {                           
    3.                         /* LED亮 */
    4.                         CORE_BOARD_LED_ON;
    5.                         /* 延时 */
    6.                         LED_DELAY;
    7.       
    8.       /* 独立操作红灯 */
    9.                         RGB_RED_LED_ON;
    10.                         LED_DELAY;
    11.                         
    12.                         RGB_RED_LED_OFF;
    13.                         LED_DELAY;
    14.       
    15.       /* 独立操作绿灯 */
    16.       RGB_GREEN_LED_ON;
    17.                         LED_DELAY;
    18.                         
    19.                         RGB_GREEN_LED_OFF;
    20.                         LED_DELAY;
    21.       
    22.       /* 独立操作蓝灯 */
    23.       RGB_BLUE_LED_ON;
    24.                         LED_DELAY;
    25.                         
    26.                         RGB_BLUE_LED_OFF;
    27.                         LED_DELAY;               

    28.       /* 整体操作红色 */
    29.                         RGB_LED_COLOR_RED;
    30.                         LED_DELAY;               
    31.       
    32.       /* 整体操作绿色 */
    33.       RGB_LED_COLOR_GREEN;
    34.                         LED_DELAY;               
    35.       
    36.       /* 整体操作蓝色 */
    37.       RGB_LED_COLOR_BLUE;
    38.                         LED_DELAY;               
    39.       
    40.       /* 整体操作黄色 */
    41.       RGB_LED_COLOR_YELLOW;
    42.                         LED_DELAY;               
    43.       
    44.       /* 整体操作紫色 */
    45.       RGB_LED_COLOR_PURPLE;
    46.                         LED_DELAY;               
    47.       
    48.       /* 整体操作青色 */
    49.       RGB_LED_COLOR_CYAN;
    50.                         LED_DELAY;               
    51.       
    52.       /* 整体操作白色 */
    53.       RGB_LED_COLOR_WHITE;
    54.                         LED_DELAY;               
    55.       
    56.       /* 整体操作黑色(全关闭) */
    57.       RGB_LED_COLOR_OFF;
    58.                         LED_DELAY;               
    59.                 }
    复制代码


    效果如下图
    195232z8gh6j68kjndtz83.gif

    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-10-8 06:12 , Processed in 0.113523 second(s), 16 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.