dwt.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /*
  2. *********************************************************************************************************
  3. *
  4. * 模块名称 : 数据观察点与跟踪(DWT)模块
  5. * 文件名称 : bsp_dwt.c
  6. * 版 本 : V1.0
  7. * 说 明 : 在CM3,CM4中可以有3种跟踪源:ETM, ITM 和DWT,本驱动主要实现
  8. * DWT中的时钟周期(CYCCNT)计数功能,此功能非常重要,可以很方便的
  9. * 计算程序执行的时钟周期个数。
  10. * 修改记录 :
  11. * 版本号 日期 作者 说明
  12. * V1.0 2015-08-18 Eric2013 正式发布
  13. *
  14. * Copyright (C), 2015-2020, 安富莱电子 www.armfly.com
  15. *
  16. *********************************************************************************************************
  17. */
  18. #include "global.h"
  19. /*
  20. *********************************************************************************************************
  21. * 寄存器
  22. *********************************************************************************************************
  23. */
  24. #define DWT_CYCCNT *(volatile unsigned int *)0xE0001004
  25. #define DWT_CR *(volatile unsigned int *)0xE0001000
  26. #define DEM_CR *(volatile unsigned int *)0xE000EDFC
  27. #define DBGMCU_CR *(volatile unsigned int *)0xE0042004
  28. #define DEM_CR_TRCENA (1 << 24)
  29. #define DWT_CR_CYCCNTENA (1 << 0)
  30. /*
  31. *********************************************************************************************************
  32. * 函 数 名: bsp_InitDWT
  33. * 功能说明: 初始化DWT. 该函数被 bsp_Init() 调用。
  34. * 形 参: 无
  35. * 返 回 值: 无
  36. *********************************************************************************************************
  37. */
  38. void dwt_init(void)
  39. {
  40. DEM_CR |= (unsigned int)DEM_CR_TRCENA; /* Enable Cortex-M4's DWT CYCCNT reg. */
  41. DWT_CYCCNT = (unsigned int)0u;
  42. DWT_CR |= (unsigned int)DWT_CR_CYCCNTENA;
  43. }
  44. /*
  45. *********************************************************************************************************
  46. * 函 数 名: bsp_DelayUS
  47. * 功能说明: 这里的延时采用CPU的内部计数实现,32位计数器
  48. * OSSchedLock(&err);
  49. * bsp_DelayUS(5);
  50. * OSSchedUnlock(&err); 根据实际情况看看是否需要加调度锁或选择关中断
  51. * 形 参: us_time 延迟长度,单位1 us
  52. * 返 回 值: 无
  53. * 说 明: 1. 主频168MHz的情况下,32位计数器计满是2^32/168000000 = 25.565秒
  54. * 建议使用本函数做延迟的话,延迟在1秒以下。
  55. * 2. 实际通过示波器测试,微妙延迟函数比实际设置实际多运行0.25us左右的时间。
  56. * 下面数据测试条件:
  57. * (1). MDK5.15,优化等级0, 不同的MDK优化等级对其没有影响。
  58. * (2). STM32F407IGT6
  59. * (3). 测试方法:
  60. * GPIOI->BSRRL = GPIO_Pin_8;
  61. * bsp_DelayUS(10);
  62. * GPIOI->BSRRH = GPIO_Pin_8;
  63. * -------------------------------------------
  64. * 测试 实际执行
  65. * bsp_DelayUS(1) 1.2360us
  66. * bsp_DelayUS(2) 2.256us
  67. * bsp_DelayUS(3) 3.256us
  68. * bsp_DelayUS(4) 4.256us
  69. * bsp_DelayUS(5) 5.276us
  70. * bsp_DelayUS(6) 6.276us
  71. * bsp_DelayUS(7) 7.276us
  72. * bsp_DelayUS(8) 8.276us
  73. * bsp_DelayUS(9) 9.276us
  74. * bsp_DelayUS(10) 10.28us
  75. * 3. 两个32位无符号数相减,获取的结果再赋值给32位无符号数依然可以正确的获取差值。
  76. * 假如A,B,C都是32位无符号数。
  77. * 如果A > B 那么A - B = C,这个很好理解,完全没有问题
  78. * 如果A < B 那么A - B = C, C的数值就是0xFFFFFFFF - B + A + 1。这一点要特别注意,正好用于本函数。
  79. *********************************************************************************************************
  80. */
  81. void delay_us(uint32_t us_time)
  82. {
  83. uint32_t tCnt, tDelayCnt;
  84. uint32_t tStart;
  85. tStart = DWT_CYCCNT; /* 刚进入时的计数器值 */
  86. tCnt = 0;
  87. tDelayCnt = us_time * (SystemCoreClock / 1000000); /* 需要的节拍数 */
  88. while (tCnt < tDelayCnt)
  89. {
  90. tCnt = DWT_CYCCNT - tStart; /* 求减过程中,如果发生第一次32位计数器重新计数,依然可以正确计算 */
  91. }
  92. }
  93. void delay_ms(uint32_t us_time)
  94. {
  95. delay_us(1000 * us_time);
  96. }