hardware_delay.c 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. #include "GD32Sys.h"
  2. #include "hardware_delay.h"
  3. /*
  4. *********************************************************************************************************
  5. * 寄存器
  6. *********************************************************************************************************
  7. */
  8. #define DWT_CYCCNT *(volatile unsigned int *)0xE0001004
  9. #define DWT_CR *(volatile unsigned int *)0xE0001000
  10. #define DEM_CR *(volatile unsigned int *)0xE000EDFC
  11. #define DBGMCU_CR *(volatile unsigned int *)0xE0042004
  12. #define DEM_CR_TRCENA (1 << 24)
  13. #define DWT_CR_CYCCNTENA (1 << 0)
  14. static volatile int system_core_clock = 400; //系统时钟
  15. /**
  16. * 初始化软件延时
  17. *
  18. * @author lxz
  19. *
  20. * @param clk 设备硬件时钟
  21. */
  22. void hw_delay_init(int clk)
  23. {
  24. system_core_clock = clk * 1000000;
  25. DEM_CR |= (unsigned int)DEM_CR_TRCENA; /* Enable Cortex-M4's DWT CYCCNT reg. */
  26. DWT_CYCCNT = (unsigned int)0u;
  27. DWT_CR |= (unsigned int)DWT_CR_CYCCNTENA;
  28. SysTick->CTRL |= 1 << 2; //SYSTICK 时钟跟系统同步
  29. SysTick->CTRL |= 1 << 1; //中断使能
  30. SysTick->LOAD = (system_core_clock / 1000) - 1; //1ms中断
  31. SysTick->CTRL |= 1 << 0; //使能systick
  32. }
  33. /**
  34. * 微妙级延时
  35. *
  36. * @author LXZ (2018/8/16)
  37. *
  38. * @param usec
  39. */
  40. void hw_delay_us(int usec)
  41. {
  42. uint32_t tCnt, tDelayCnt;
  43. uint32_t tStart;
  44. tStart = DWT_CYCCNT; /* 刚进入时的计数器值 */
  45. tCnt = 0;
  46. tDelayCnt = usec * (system_core_clock / 1000000); /* 需要的节拍数 */
  47. while (tCnt < tDelayCnt)
  48. {
  49. tCnt = DWT_CYCCNT - tStart; /* 求减过程中,如果发生第一次32位计数器重新计数,依然可以正确计算 */
  50. }
  51. }
  52. /**
  53. * 获取当前的微秒值,该值只是近似值,偏差一个us
  54. *
  55. * @author lxz (2019/5/30/周四)
  56. *
  57. * @param void
  58. *
  59. * @return int
  60. */
  61. int hw_read_us(void)
  62. {
  63. uint32_t usec = system_core_clock / 1000000;
  64. return (DWT_CYCCNT + (usec >> 1)) / usec;
  65. }