一个简易的软件定时器

时间:2022-06-25 07:13:06

在一些项目中硬件的定时紧缺,这时候需要我们利用原先的一个硬件定时器进行扩展。利用硬件定时器生产一个基准的节拍来。

 

一个简易的软件定时器一个简易的软件定时器
  1 #include <string.h>
  2 #include "soft_timer.h"
  3 
  4 /**
  5  * @brief 定时器队列
  6  */
  7 soft_timer_t SoftTimer[SOFT_TIMER_MAX_NUM];
  8 
  9 #if SOFT_TIMER_USE_OS
 10 /**
 11  * @brief 进入临界区(依赖具体环境具体实现)
 12  */
 13 void soft_timer_enter_critical(void)
 14 {
 15 }
 16 
 17 /**
 18  * @brief 退出临界区(依赖具体环境具体实现)
 19  */
 20 void soft_timer_exit_critical(void)
 21 {
 22 }
 23 #endif
 24 
 25 /**
 26  * @brief 启动软件定时器
 27  * @param timer 软件定时器编号
 28  * @param mode 软件定时器模式
 29  * @param time 软件定时器定时时间
 30  * @param soft_timer_cb 软件定时器回调函数指针
 31  * @param soft_timer_arg 回调函数传递的实参
 32  * @note  定时时间必须是10ms的整数倍
 33  */
 34 soft_timer_error_t soft_timer_start(uint8_t timer, uint8_t mode, uint32_t  time, SOFT_TIMER_CB soft_timer_cb, void * soft_timer_arg)
 35 {
 36     if (timer >= SOFT_TIMER_MAX_NUM) /* 软件定时器编号不能超过最大值 */
 37     {
 38         return SOFT_TIMER_PARA_ERR;
 39     }
 40 
 41 #if SOFT_TIMER_USE_OS
 42     soft_timer_enter_critical();
 43 #endif
 44 
 45     /* 初始化定时器需要超时的节拍数 */
 46     SoftTimer[timer].init_tick =  time;
 47     /* 初始化定时器实际超时时的系统节拍数 */
 48     SoftTimer[timer].timeout_tick = 0;
 49     SoftTimer[timer].mode = mode;
 50     SoftTimer[timer].soft_timer_cb = soft_timer_cb;
 51     SoftTimer[timer].soft_timer_arg = soft_timer_arg;
 52     SoftTimer[timer].state = SOFT_TIMER_START; /* 开启当前编号的软件定时器 */
 53 
 54 #if SOFT_TIMER_USE_OS
 55     soft_timer_exit_critical();
 56 #endif
 57 
 58     return SOFT_TIMER_NO_ERR;
 59 }
 60 
 61 /**
 62  * @brief 停止当前编号的软件定时器
 63  * @param timer 软件定时器编号
 64  */
 65 soft_timer_error_t soft_timer_stop(uint8_t timer)
 66 {
 67     if (timer >= SOFT_TIMER_MAX_NUM)
 68     {
 69         return SOFT_TIMER_PARA_ERR;
 70     }
 71 
 72 #if SOFT_TIMER_USE_OS
 73     soft_timer_enter_critical();
 74 #endif
 75 
 76     SoftTimer[timer].state = SOFT_TIMER_STOP;
 77 
 78 #if SOFT_TIMER_USE_OS
 79     soft_timer_exit_critical();
 80 #endif
 81 
 82     return SOFT_TIMER_NO_ERR;
 83 }
 84 
 85 /**
 86  * @brief 软件定时器实时参数刷新
 87  * @note  该函数应该是放在中断里
 88  * @note  该函数刷新频率决定了软件定时器的时基
 89  */
 90 void soft_timer_in_isr(void)
 91 {
 92     uint8_t index;
 93 
 94 #if SOFT_TIMER_USE_OS
 95     soft_timer_enter_critical();
 96 #endif
 97 
 98     for (index = 0; index < SOFT_TIMER_MAX_NUM; index++)
 99     {
100         if (SoftTimer[index].state)
101         {
102 
103             if ( SoftTimer[index].timeout_tick++ >= SoftTimer[index].init_tick )
104             {
105 
106                 if (SoftTimer[index].mode == SOFT_TIMER_ALWAYS)
107                 {
108                     SoftTimer[index].timeout_tick = 0;
109                 }
110                 else
111                 {
112                     SoftTimer[index].state = SOFT_TIMER_STOP;
113                 }
114 
115                 SoftTimer[index].soft_timer_cb(SoftTimer[index].soft_timer_arg);
116             }
117 
118         }
119     }
120 
121 #if SOFT_TIMER_USE_OS
122     soft_timer_exit_critical();
123 #endif
124 }
soft_timer.C
一个简易的软件定时器一个简易的软件定时器
  1 #include <string.h>
  2 #include "soft_timer.h"
  3 
  4 /**
  5  * @brief 定时器队列
  6  */
  7 soft_timer_t SoftTimer[SOFT_TIMER_MAX_NUM];
  8 
  9 #if SOFT_TIMER_USE_OS
 10 /**
 11  * @brief 进入临界区(依赖具体环境具体实现)
 12  */
 13 void soft_timer_enter_critical(void)
 14 {
 15 }
 16 
 17 /**
 18  * @brief 退出临界区(依赖具体环境具体实现)
 19  */
 20 void soft_timer_exit_critical(void)
 21 {
 22 }
 23 #endif
 24 
 25 /**
 26  * @brief 启动软件定时器
 27  * @param timer 软件定时器编号
 28  * @param mode 软件定时器模式
 29  * @param time 软件定时器定时时间
 30  * @param soft_timer_cb 软件定时器回调函数指针
 31  * @param soft_timer_arg 回调函数传递的实参
 32  * @note  定时时间必须是10ms的整数倍
 33  */
 34 soft_timer_error_t soft_timer_start(uint8_t timer, uint8_t mode, uint32_t  time, SOFT_TIMER_CB soft_timer_cb, void * soft_timer_arg)
 35 {
 36     if (timer >= SOFT_TIMER_MAX_NUM) /* 软件定时器编号不能超过最大值 */
 37     {
 38         return SOFT_TIMER_PARA_ERR;
 39     }
 40 
 41 #if SOFT_TIMER_USE_OS
 42     soft_timer_enter_critical();
 43 #endif
 44 
 45     /* 初始化定时器需要超时的节拍数 */
 46     SoftTimer[timer].init_tick =  time;
 47     /* 初始化定时器实际超时时的系统节拍数 */
 48     SoftTimer[timer].timeout_tick = 0;
 49     SoftTimer[timer].mode = mode;
 50     SoftTimer[timer].soft_timer_cb = soft_timer_cb;
 51     SoftTimer[timer].soft_timer_arg = soft_timer_arg;
 52     SoftTimer[timer].state = SOFT_TIMER_START; /* 开启当前编号的软件定时器 */
 53 
 54 #if SOFT_TIMER_USE_OS
 55     soft_timer_exit_critical();
 56 #endif
 57 
 58     return SOFT_TIMER_NO_ERR;
 59 }
 60 
 61 /**
 62  * @brief 停止当前编号的软件定时器
 63  * @param timer 软件定时器编号
 64  */
 65 soft_timer_error_t soft_timer_stop(uint8_t timer)
 66 {
 67     if (timer >= SOFT_TIMER_MAX_NUM)
 68     {
 69         return SOFT_TIMER_PARA_ERR;
 70     }
 71 
 72 #if SOFT_TIMER_USE_OS
 73     soft_timer_enter_critical();
 74 #endif
 75 
 76     SoftTimer[timer].state = SOFT_TIMER_STOP;
 77 
 78 #if SOFT_TIMER_USE_OS
 79     soft_timer_exit_critical();
 80 #endif
 81 
 82     return SOFT_TIMER_NO_ERR;
 83 }
 84 
 85 /**
 86  * @brief 软件定时器实时参数刷新
 87  * @note  该函数应该是放在中断里
 88  * @note  该函数刷新频率决定了软件定时器的时基
 89  */
 90 void soft_timer_in_isr(void)
 91 {
 92     uint8_t index;
 93 
 94 #if SOFT_TIMER_USE_OS
 95     soft_timer_enter_critical();
 96 #endif
 97 
 98     for (index = 0; index < SOFT_TIMER_MAX_NUM; index++)
 99     {
100         if (SoftTimer[index].state)
101         {
102 
103             if ( SoftTimer[index].timeout_tick++ >= SoftTimer[index].init_tick )
104             {
105 
106                 if (SoftTimer[index].mode == SOFT_TIMER_ALWAYS)
107                 {
108                     SoftTimer[index].timeout_tick = 0;
109                 }
110                 else
111                 {
112                     SoftTimer[index].state = SOFT_TIMER_STOP;
113                 }
114 
115                 SoftTimer[index].soft_timer_cb(SoftTimer[index].soft_timer_arg);
116             }
117 
118         }
119     }
120 
121 #if SOFT_TIMER_USE_OS
122     soft_timer_exit_critical();
123 #endif
124 }
soft_timer.H

需要注意的地方是:其回调函数运行时间要短。

 

下次有空弄个带链表排序的软定时器