software_timer.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #include "GD32Sys.h"
  2. //1秒换算成1us的倍数
  3. #define US_PER_SECOND 1000000
  4. //当前的时间
  5. static int cur_second = 0;
  6. static int cur_ms = 0;
  7. static int reload_value = 0;
  8. unsigned long dwTickCount = 0;
  9. static void defaut_tick_hook(void);
  10. static void (*systick_hook)() = defaut_tick_hook;
  11. /**
  12. * 默认的1ms周期中断
  13. *
  14. * @author lxz
  15. *
  16. * @param void
  17. */
  18. static void defaut_tick_hook(void)
  19. {
  20. }
  21. /**
  22. * 定时中断,1ms
  23. *
  24. * @author LXZ (010120)
  25. */
  26. void SysTick_Handler()
  27. {
  28. dwTickCount++;
  29. if (++cur_ms >= 1000)
  30. {
  31. cur_ms = 0;
  32. cur_second++;
  33. }
  34. systick_hook();
  35. }
  36. /**
  37. * 设置ms中断定时器的钩子函数
  38. *
  39. * @author lxz
  40. *
  41. * @param hook
  42. */
  43. void sw_tick_set_hook(void (*hook)())
  44. {
  45. if (hook != 0)
  46. {
  47. systick_hook = hook;
  48. }
  49. }
  50. /**
  51. * 初始化定时器
  52. *
  53. * @author lxz
  54. *
  55. * @param void
  56. */
  57. void sw_timer_init(int clk)
  58. {
  59. reload_value = clk * 1000 - 1;
  60. /* setup systick timer for 1000Hz interrupts */
  61. if (SysTick_Config(clk * 1000U)){
  62. /* capture error */
  63. while (1){
  64. }
  65. }
  66. /* configure the systick handler priority */
  67. NVIC_SetPriority(SysTick_IRQn, 0x00U);
  68. }
  69. /**
  70. * 获取当前的定时器时间
  71. *
  72. * @author lxz
  73. *
  74. * @param timer
  75. */
  76. void sw_timer_now(sw_timer_t *timer)
  77. {
  78. int second;
  79. int us;
  80. int ms;
  81. do
  82. {
  83. ms = cur_ms;
  84. second = cur_second;
  85. us = SysTick->VAL;
  86. } while (ms != cur_ms);
  87. timer->second = second;
  88. timer->usec = (ms * 1000) + (reload_value - us) * 1000 / reload_value;
  89. }
  90. /**
  91. * 初始化一个定时器实体用于时间比较
  92. *
  93. * @author lxz
  94. *
  95. * @param timer object 定时实体
  96. * @param second 要延时的秒单位
  97. * @param usec 要延时的毫秒单位
  98. */
  99. void sw_timer_start(sw_timer_t *timer, int sec, int usec)
  100. {
  101. sw_timer_now(timer);
  102. sw_timer_delay(timer, sec, usec);
  103. }
  104. /**
  105. * 返回定时器是否已经计时到了
  106. *
  107. * @author lxz
  108. *
  109. * @param timer 定时器实体
  110. *
  111. * @return int
  112. */
  113. int sw_timer_expire(sw_timer_t *timer)
  114. {
  115. sw_timer_t now;
  116. sw_timer_now(&now);
  117. if (timer->second < now.second ||
  118. (timer->second == now.second && timer->usec <= now.usec))
  119. return 1;
  120. return 0;
  121. }
  122. /**
  123. * 对当关定时器进行时间延后
  124. *
  125. * @author lxz
  126. *
  127. * @param timer 定时器实体
  128. * @param sec 要延后的秒数
  129. * @param usec 要延后的微秒数
  130. *
  131. * @return int
  132. */
  133. void sw_timer_delay(sw_timer_t *timer, int sec, int usec)
  134. {
  135. timer->usec += usec;
  136. timer->second += sec + timer->usec / US_PER_SECOND;
  137. timer->usec %= US_PER_SECOND;
  138. }