单片机中的软定时器

因单片机中常有一些控制与延时关联,这些操作并不需要特别高的精度,为了少敲点字,故做了这个单片机软定时器,不足之处,欢迎指正。

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

单片机中的软定时器的相关文章

用定时器中断,单片机中断处理时间大于定时器定时时间会怎样?

如果是不同的中断类型是可以根据优先级嵌套,如果是同一中断类型(如题), 有三种结果:1.马上进入新的中断处理(中断嵌套) 2.等待中断处理完再进入新的中断处理 3.出错. 单片机中断处理时间大于定时器定时时间,在下次中断时间到时,因为中断是同一类型.同一优先级,所以不会马上进入新的中断处理. 而是在本次中断处理结束后,单片机又马上进入新的定时器中断函数,主函数中的语句可能会没有机会运行下去,会影响后面中断的实时性.所以答案为2. 如果为了避免中断嵌套(同一优先级不会发生),在中断处理中人为的在进

Android学习笔记_78_ Android开发中使用软引用和弱引用防止内存溢出

在<Effective Java 2nd Edition>中,第6条"消除过期的对象引用"提到,虽然Java有 垃圾回收机制,但是只要是自己管理的内存,就应该警惕内存泄露的问题,例如的对象池.缓存中的过期对象都有可能引发内存泄露的问题.书中还提到可以用 WeakHashMap来作为缓存的容器可以有效解决这一问题.之前也确实遇到过类似问题,但是没有接触过"弱引用"相关的问题,于是查阅了一些资料. <Java 理论与实践: 用弱引用堵住内存泄漏>

【网络协议】TCP中的四大定时器

前言 对于每个TCP连接,TCP一般要管理4个不同的定时器:重传定时器.坚持定时器.保活定时器.2MSL定时器. 重传定时器 非常明显重传定时器是用来计算TCP报文段的超时重传时间的(至于超时重传时间的确定,这里涉及到一大堆的算法,书上有说,我这里不细谈了).每发送一个报文段就会启动重传定时器,假设在定时器时间到后还没收到对该报文段的确认,就重传该报文段,并将重传定时器复位,又一次计算:假设在规定时间内收到了对该报文段的确认,则撤销该报文段的重传定时器. 坚持定时器 上篇文章中已经提到了,主要是

RIP中4个定时器

①updata timer(组播定期更新时间):默认每30s/次,组播地址224.0.0.9 ②invalid timer(失效时间):默认是180s ③flush timer(刷新时间):cisco默认为240s ④holddown timer(死亡时间):默认180s 每个路由条目建立后每30s组播更新一次,并且开始180s invalid timer倒计时,如果如果这个时间内没有收到更新,则该路由条目自动变成16跳,即不可达(失效) x.x.x.x is possibly down flu

linux中的软、硬链接

linux中的软.硬链接 硬链接 硬链接(hard link),如果文件B是文件A的硬链接,则A的inode节点号与B的inode节点号相同,即一个inode节点对应两个不同的文件名,两个文件名指向同一个文件,A和B对文件系统来说是完全平等的.如果删除了其中一个,对另外一个没有影响.每增加一个文件名,inode节点上的链接数增加一,每删除一个对应的文件名,inode节点上的链接数减一,直到为0,inode节点和对应的数据块被回收.注:文件和文件名是不同的东西,rm A删除的只是A这个文件名,而A

九、Android学习笔记_ Android开发中使用软引用和弱引用防止内存溢出

在<Effective Java 2nd Edition>中,第6条"消除过期的对象引用"提到,虽然Java有 垃圾回收机制,但是只要是自己管理的内存,就应该警惕内存泄露的问题,例如的对象池.缓存中的过期对象都有可能引发内存泄露的问题.书中还提到可以用 WeakHashMap来作为缓存的容器可以有效解决这一问题.之前也确实遇到过类似问题,但是没有接触过"弱引用"相关的问题,于是查阅了一些资料. <Java 理论与实践: 用弱引用堵住内存泄漏>

iOS中的三大定时器

iOS开发中定时器经常会用到,iOS中常用的定时器有三种,分别是NSTime,CADisplayLink和GCD. NSTimer 方式1 // 创建定时器 NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(test) userInfo:nil repeats:YES]; // 停止定时器 [timer invalidate]; 方式2 // 创建定时器 NSTime

一种单片机支持WiFi的应用——SimpleWiFi在单片机中的应用

一种单片机支持WiFi的应用——SimpleWiFi在单片机中的应用 先上图: 现在的智能控制都是基于微控制器,随着智能的手持终端的普及,基于智能终端的控制就会越来越普遍. WIFI便是其中的一种.WiFi用于智能家居控制,有着其得天独厚的优势.其优势如下: 优势一:WiFi终端设备现在基本上已经普及,WiFi已经智能手持终端的标配.大到笔记本.Pad,小到手机,WiFi已经是无所不在. 优势二:WiFi作为无线局域网的技术标准,能够通过无线路由器与现有的互联网进行互联互通.没有任何的技术以及协

单片机中 负跳变和高脉冲是什么

在单片机中,负跳变指平由高电平变成低电平的过程,也叫下降沿,高脉冲就是正脉冲,给一个上升沿. 负跳变指令检测它前面的逻辑状态.如果上个程序扫描周期是1,本周期是0,则它后面的逻辑状态在本周期的剩余扫描时间内为1, 该指令仅在一个扫描周期内有效. 高脉冲即从逻辑0变化到逻辑1再变化到逻辑0,如此便是一个高脉冲.在单片机中定义高脉冲就是让某个I/O先输出逻辑0,接着保持一定的时间(延时),再输出逻辑1,同样保持一定的时间(延时),最后再转变输出为逻辑0+延时.