dwt.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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 "dwt.h"
  19. #include "bsp.h"
  20. /*
  21. *********************************************************************************************************
  22. * 寄存器
  23. *********************************************************************************************************
  24. */
  25. #define DWT_CYCCNT *(volatile unsigned int *)0xE0001004
  26. #define DWT_CR *(volatile unsigned int *)0xE0001000
  27. #define DEM_CR *(volatile unsigned int *)0xE000EDFC
  28. #define DBGMCU_CR *(volatile unsigned int *)0xE0042004
  29. #define DEM_CR_TRCENA (1 << 24)
  30. #define DWT_CR_CYCCNTENA (1 << 0)
  31. /*
  32. *********************************************************************************************************
  33. * 函 数 名: dwt_init
  34. * 功能说明: 初始化DWT. 该函数被 bsp_Init() 调用。
  35. * 形 参: 无
  36. * 返 回 值: 无
  37. *********************************************************************************************************
  38. */
  39. void dwt_init(void)
  40. {
  41. DEM_CR |= (unsigned int)DEM_CR_TRCENA; /* Enable Cortex-M4's DWT CYCCNT reg. */
  42. DWT_CYCCNT = (unsigned int)0u;
  43. DWT_CR |= (unsigned int)DWT_CR_CYCCNTENA;
  44. }
  45. /*
  46. *********************************************************************************************************
  47. * 函 数 名: bsp_DelayUS
  48. * 功能说明: 这里的延时采用CPU的内部计数实现,32位计数器
  49. * OSSchedLock(&err);
  50. * bsp_DelayUS(5);
  51. * OSSchedUnlock(&err); 根据实际情况看看是否需要加调度锁或选择关中断
  52. * 形 参: time 延迟长度,单位1 us
  53. * 返 回 值: 无
  54. * 说 明: 1. 主频168MHz的情况下,32位计数器计满是2^32/168000000 = 25.565秒
  55. * 建议使用本函数做延迟的话,延迟在1秒以下。
  56. * 2. 实际通过示波器测试,微妙延迟函数比实际设置实际多运行0.25us左右的时间。
  57. * 下面数据测试条件:
  58. * (1). MDK5.15,优化等级0, 不同的MDK优化等级对其没有影响。
  59. * (2). STM32F407IGT6
  60. * (3). 测试方法:
  61. * GPIOI->BSRRL = GPIO_Pin_8;
  62. * bsp_DelayUS(10);
  63. * GPIOI->BSRRH = GPIO_Pin_8;
  64. * -------------------------------------------
  65. * 测试 实际执行
  66. * bsp_DelayUS(1) 1.2360us
  67. * bsp_DelayUS(2) 2.256us
  68. * bsp_DelayUS(3) 3.256us
  69. * bsp_DelayUS(4) 4.256us
  70. * bsp_DelayUS(5) 5.276us
  71. * bsp_DelayUS(6) 6.276us
  72. * bsp_DelayUS(7) 7.276us
  73. * bsp_DelayUS(8) 8.276us
  74. * bsp_DelayUS(9) 9.276us
  75. * bsp_DelayUS(10) 10.28us
  76. * 3. 两个32位无符号数相减,获取的结果再赋值给32位无符号数依然可以正确的获取差值。
  77. * 假如A,B,C都是32位无符号数。
  78. * 如果A > B 那么A - B = C,这个很好理解,完全没有问题
  79. * 如果A < B 那么A - B = C, C的数值就是0xFFFFFFFF - B + A + 1。这一点要特别注意,正好用于本函数。
  80. *********************************************************************************************************
  81. */
  82. void us_delay(uint32_t time)
  83. {
  84. uint32_t count, tcnt;
  85. uint32_t tstart;
  86. tstart = DWT_CYCCNT; /* 刚进入时的计数器值 */
  87. count = 0;
  88. tcnt = time * (SystemCoreClock / 1000000); /* 需要的节拍数 */
  89. while (count < tcnt)
  90. {
  91. count = DWT_CYCCNT - tstart; /* 求减过程中,如果发生第一次32位计数器重新计数,依然可以正确计算 */
  92. }
  93. }
  94. /*
  95. *********************************************************************************************************
  96. * 函 数 名: bsp_DelayMS
  97. * 功能说明: 为了让底层驱动在带RTOS和裸机情况下有更好的兼容性
  98. * 专门制作一个阻塞式的延迟函数,在底层驱动中ms毫秒延迟主要用于初始化,并不会影响实时性。
  99. * 形 参: n 延迟长度,单位1 ms
  100. * 返 回 值: 无
  101. *********************************************************************************************************
  102. */
  103. void ms_delay(uint32_t time)
  104. {
  105. us_delay(1000 * time);
  106. }
  107. /***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/