在一些项目中硬件的定时紧缺,这时候需要我们利用原先的一个硬件定时器进行扩展。利用硬件定时器生产一个基准的节拍来。
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 }
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 }
需要注意的地方是:其回调函数运行时间要短。
下次有空弄个带链表排序的软定时器