因单片机中常有一些控制与延时关联,这些操作并不需要特别高的精度,为了少敲点字,故做了这个单片机软定时器,不足之处,欢迎指正。
timer.h
1 #ifndef __SOFT_TIMER_H__ 2 #define __SOFT_TIMER_H__ 3 4 //#define TIMEBASE_FREQ 1000 5 // 6 #define ONESHOT_TIMER 0 7 #define PERIODIC_TIMER 1 8 9 //time vector size ,可同时使用的最大定时器数 10 #define TIMER_MAX 10 11 12 #define BOOL unsigned char 13 14 #ifndef FALSE 15 #define FALSE 0 16 #endif 17 18 #ifndef TRUE 19 #define TRUE 1 20 #endif 21 22 typedef struct _tagSystemTimeInfo 23 { 24 unsigned long tick; // ms 25 unsigned long msec; // ms 26 unsigned long sec; //sec = tick /1000 27 unsigned long min; // min = sec /60 28 unsigned long hour; 29 unsigned long timeoutFlag; 30 }_SystemTimeInfo; 31 32 typedef enum{ 33 TIMEOUT_SECOND = 0, 34 TIMEOUT_MINUTE, 35 TIMEOUT_HOUR, 36 TIMEOUT_DAY, 37 }TimeoutDef; 38 39 typedef void (*pCallback)(void*); 40 41 //返回开机运行,单位ms 42 unsigned long GetTickCount(void); 43 44 /*获取时间信号: 45 type 含义: 46 TIMEOUT_SECOND ,秒信号,每秒一个 47 TIMEOUT_MINUTE ,分信号,每分一个 48 TIMEOUT_HOUR ,小时信号,每小时一个 49 TIMEOUT_DAY ,天信号,每天一个 50 */ 51 BOOL GetTimeoutSignal(TimeoutDef type); 52 void ClrTimeoutSignal(TimeoutDef type); 53 //更新信号, 此函数需1ms调用一次 54 void IncSysTime(void); 55 56 /*创建一个定时器, 57 参数: 58 id: 定时器id, 用killTimer(id) 销毁定时器 59 uElapse: 定时周期,单位ms, 60 pFunc:定时器超时后回调函数 61 para :定时器回调函数参数 62 event_type:定时器类型,PERIODIC_TIMER为周期定时器,ONESHOT_TIMER为单次定时器 63 返回值:1代表创建成功,0代表失败 64 */ 65 BOOL SetTimer(unsigned int id,unsigned long uElapse,pCallback pFunc,void *para,unsigned int event_type); 66 67 //销毁指定的定时器 68 void killTimer(unsigned int id); 69 70 //定时回调,主循环中调用此函数 71 void _TimerServer(void); 72 73 //计时,1ms调用1次 74 void _TimerCountDown(void); // call it in timer isr 75 76 77 #endif
timer.c
1 #include "timer.h" 2 3 typedef struct _tagTimer{ 4 BOOL bEnabled; 5 unsigned int id; 6 unsigned long elapse; 7 unsigned long interval; 8 BOOL signal; 9 pCallback pFunc; 10 void *para; 11 unsigned int event_type; 12 }_Timer; 13 14 static _Timer _timer[TIMER_MAX]; 15 16 static _SystemTimeInfo SysTime = {0,1000-1,60-1,60-1,24-1,0} ; 17 18 unsigned long GetSystemTime() 19 { 20 return SysTime.sec; 21 } 22 23 unsigned long GetTickCount(void) 24 { 25 return SysTime.tick; 26 } 27 28 BOOL GetTimeoutSignal(TimeoutDef type) 29 { 30 return (SysTime.timeoutFlag >> type)&0x1; 31 } 32 33 void ClrTimeoutSignal(TimeoutDef type) 34 { 35 SysTime.timeoutFlag &= ~(0x1<<type); 36 } 37 38 // call it every millisecond 39 void IncSysTime(void) 40 { 41 ++SysTime.tick; 42 ++SysTime.msec; 43 if(SysTime.msec) 44 { 45 --SysTime.msec; 46 } 47 else 48 { 49 SysTime.timeoutFlag |= (1<<TIMEOUT_SECOND); 50 SysTime.msec = 1000 - 1; 51 if(SysTime.sec) 52 { 53 --SysTime.sec; 54 } 55 else 56 { 57 SysTime.timeoutFlag |= (1<<TIMEOUT_MINUTE); 58 SysTime.sec = 60 - 1; 59 if(SysTime.min) 60 { 61 --SysTime.min; 62 } 63 else 64 { 65 SysTime.timeoutFlag |= (1<<TIMEOUT_HOUR); 66 SysTime.min = 60 - 1; 67 if(SysTime.hour) 68 { 69 --SysTime.hour; 70 } 71 else 72 { 73 SysTime.timeoutFlag |= (1<<TIMEOUT_DAY); 74 SysTime.hour = 24 - 1; 75 } 76 } 77 } 78 } 79 } 80 81 void DefaultTimerProc(unsigned int id,void *para); 82 83 84 /****************************************************************************** 85 * @funtion SetTimer 86 * @author Kelvin 87 * @date 07-apr-2013 88 * @brief 89 * return nonzero if succeed, zero means failed 90 * @param: 91 * @Input: 92 id : nonzero , 93 uElapse : millisecond 94 * @Output: None 95 * @Retval: None 96 * 97 * @modification history 98 * -------------------- 99 * 01a, 07-apr-2013, Kelvin written 100 * -------------------- 101 ******************************************************************************/ 102 BOOL SetTimer(unsigned int id,unsigned long uElapse,pCallback pFunc,void *para,unsigned int event_type) 103 { 104 int i = 0, ret = 0,j = TIMER_MAX; 105 106 for(i = TIMER_MAX ;i != 0 ;--i) 107 { 108 if(_timer[i-1].bEnabled == FALSE) 109 { 110 j = i-1 ; 111 } 112 else 113 { 114 if(_timer[i-1].id == id) 115 { 116 j = i- 1; 117 break; 118 } 119 } 120 } 121 122 if(j != TIMER_MAX) 123 { 124 _timer[j].pFunc = pFunc; 125 _timer[j].para = para; 126 _timer[j].elapse = uElapse; 127 _timer[j].interval = uElapse; 128 _timer[j].signal = 0; 129 _timer[j].id = id; 130 _timer[j].bEnabled = TRUE; 131 _timer[j].event_type = event_type; 132 ret = id; 133 } 134 return ret?1:0; 135 } 136 137 void killTimer(unsigned int id) 138 { 139 int i = 0; 140 for(i = 0;i != TIMER_MAX;++i) 141 { 142 if((_timer[i].id == id)&&(_timer[i].bEnabled)) 143 { 144 _timer[i].bEnabled = FALSE; 145 _timer[i].signal = 0; 146 _timer[i].id = 0; 147 break; 148 } 149 } 150 } 151 152 void _TimerServer(void) 153 { 154 int i =0; 155 for(i = 0;i != TIMER_MAX;++i) 156 { 157 if(_timer[i].signal) 158 { 159 _timer[i].signal = 0; 160 if(_timer[i].pFunc) 161 { 162 (*_timer[i].pFunc)(_timer[i].para); 163 } 164 else 165 { 166 DefaultTimerProc(_timer[i].id,_timer[i].para); 167 } 168 } 169 } 170 } 171 172 173 void _TimerCountDown(void) 174 { 175 int i =0; 176 for(i = 0;i != TIMER_MAX;++i) 177 { 178 if(_timer[i].bEnabled) 179 { 180 if( _timer[i].elapse) 181 { 182 --_timer[i].elapse; 183 } 184 else 185 { 186 _timer[i].elapse = _timer[i].interval; 187 _timer[i].signal = 1; 188 if(_timer[i].event_type == ONESHOT_TIMER) _timer[i].bEnabled = 0; 189 } 190 } 191 } 192 } 193 194 void DefaultTimerProc(unsigned int id,void *para) 195 { 196 197 198 }
单片机中的软定时器
时间: 2024-10-04 15:59:14