你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【开源】软件定时器优化版本

[复制链接]
Inc_brza 发布时间:2018-1-24 18:35
一、从我以前的贴子有给大家分享过软件定时器,刚好无聊再优化一下。二、
' O) u  K6 y. _8 C3 j      首先介绍一个unsigned int这个类型,他是一个无符号16bit(32bit)类型,为什么是16bit又说32bit呢?因为在不同的cpu系统中,他可以是2个字节,或者是4个字节。所以在使用的时候,我们要注意一个问题:
# u" x+ e5 T6 C$ V$ u* G" g例如:
  L; |5 P4 L# P# t6 N$ _4 E* w
  1. unsigned int var = 0x1234;
    + x  E+ V5 z$ p# F8 @
  2. var = var << 16 >> 16;
复制代码
如果对于32bit来说,var = 0x1234, 然而对于16bit来说,var = 0, 所以,在实际应用中,我们更倾向于使用以下类型5 @5 b4 x7 O7 m( k6 @
  1. typedef signed char int8_t;. y3 D& ], ~+ |# K: y2 H- x
  2. typedef unsigned char uint8_t;
    3 Z9 }) [$ w4 [* t* w+ V- t
  3. typedef signed short int16_t;
    & B+ q& }3 a5 `) p: P, `' H
  4. typedef unsigned short uint16_t;
    3 L7 Q/ ~& q+ n5 ]6 y
  5. typedef signed long int32_t;
    ( P( Z" ?; Q6 D* ~, y- P* D
  6. typedef unsigned long uint32_t;
复制代码
这是第一点,另外还有一点,就是无符号变量的一个回环特性。
) G% U2 m6 t8 G对一个unsigned 类型的变量进行++操作, 当变量溢出后会返回0。利用这个特性,我们可以在一些特殊应用程序设计中利用他的回环特性而不需要在后面增加一溢出判断,以减少代码量。我一直沿用很久的软件定时器,就是用了这一回环特性。) _3 G! G7 X1 l/ ?- j: [$ @3 Z
软件定时器,从始至终都是围绕一个tick变量操作,理所当然,这个tick将会在一个硬件定时器上进行++操作来确定tick的时基间隔。
  B5 |6 D! y$ m- H' X9 ^# H) \( Y所以,软件定时器里有一个全局变量; f% a8 ]; Q: j
  1. uint32_t stmr_tick;
复制代码
在提供api方面,应该提供以下操作:
6 Y- f' t6 M# {7 _2 R. a1、初始化软件定时器
0 c; n* v$ ]% [& H, I4 u2、创建一个软件定时器3 [& \$ u# O& d: A. [0 _) z
3、让一个软件定时器开始工作7 o* O% T  H3 w- _$ A9 f3 S0 H
4、让一个软件定时器停止工作2 K) t  [0 c: {0 z9 c* H1 m
5、删除一个软件定时器; ?' M! x% i  b/ C4 g8 B
在这里,我们使用一个内部堆的概念来把可以提供的软件定时器个数集中在一起:
1 c0 A8 u' @, D2 t) J
  1. struct ifs_stmr_t {4 f: U/ N1 n  U+ z% ?- M8 c
  2.     ifs_uint32_t timer_count;6 _- Q# J, j7 n( C5 V% j4 \
  3.     ifs_uint32_t time_out;
    $ W$ u1 J5 R/ ]2 m
  4.     void (*time_out_callback)(void *param);
    # a7 o' Z% m/ k. n
  5.     void *param;3 ]+ ?2 K$ |! m6 U
  6.     ifs_uint8_t timer_flag;3 _, z9 H' r, l9 H5 ]( y
  7.     struct option {! E8 V9 u0 C0 Y! Y% Z
  8.         ifs_uint8_t is_active : 1;+ l6 G, F( l2 |' U. J5 M
  9.         ifs_uint8_t is_alive  : 1;: P) |: L+ I1 S+ o
  10.         ifs_uint8_t nc        : 6;   
    1 K3 q0 O0 e  L$ K  w
  11.     }opt;/ o2 a6 @" o. k/ e
  12. } timer_list[SOFT_TIMERS_MAX];
复制代码
下面是每一个函数的具体代码:
+ y6 E6 v( d4 C+ H
  1. void ifs_stmr_init(void)
    6 c& X, h' {8 j! Y% o/ G
  2. {0 \, j/ N" C1 C
  3.     ifs_uint32_t i;
      g+ ]1 `9 E8 E( O
  4.     for (i = 0; i < SOFT_TIMERS_MAX; i++) {. L3 B8 l, _  y3 I" V! _/ \: ]) M- n
  5.         timer_list[i].timer_count = 0;  o$ W: d! [& g
  6.         timer_list[i].timer_flag = 0;6 X! o$ `" h, M  d: l+ o; p
  7.         timer_list[i].time_out = 0;
    & W6 Z2 f  |1 r8 ^  x( o
  8.         timer_list[i].time_out_callback = NULL;) ^6 M% |! h7 D/ i5 R3 C4 O
  9.         timer_list[i].param = NULL;5 M6 \* l6 y" \2 M( C
  10.         timer_list[i].opt.is_active = 0;
    7 A. B9 T* I/ P. C& E. k
  11.         timer_list[i].opt.is_alive = 0;* b! r$ x. g" p0 i
  12.     }* c+ E6 }2 U+ U
  13.     stmr_ticks = 0;+ j) u  |6 ?' ]. m; }3 P
  14. }
复制代码
  1. ifs_stmr_handle ifs_stmr_registered(ifs_uint32_t period, 9 \- @6 A% ?- a1 g
  2.                                       timer_out_callback *callback,
    " _. j: g' j" p2 m6 P: n- Z  Z) `
  3.                                       void *callback_param,
    / Y, |; k3 s6 r' v
  4.                                       ifs_uint8_t flag)7 U4 u; j& |7 E8 Z1 |4 P1 R2 |
  5. {# @1 L9 ^# W/ E8 g2 S1 K) y! q
  6.     int i;
    * Z7 f" B# X' \
  7.    
    4 ~0 v( l+ D9 h/ w7 q& c8 t
  8.     if (callback == NULL) return -1;
    , F; H2 f3 f" W7 u* A8 J
  9.     9 `: L0 i( C4 F. W1 t
  10.     for (i = 0; i < SOFT_TIMERS_MAX; i++) {
    8 o( g9 i. k6 ~* [8 J9 l' g
  11.         if (timer_list[i].opt.is_alive) continue;" s! t# s5 |* h3 y/ ?; Z( b
  12.         timer_list[i].opt.is_alive = 1;
    ; U# X0 l8 u) w% R. ~/ U& y
  13.         timer_list[i].opt.is_active = 0;' g1 `: t% M0 K2 x( `( y
  14.         timer_list[i].time_out = period;1 p# `' V& X- R/ ^0 {. [
  15.         timer_list[i].time_out_callback = callback;
    * w' j8 R" n: }+ d( [& o! H, |
  16.         timer_list[i].param = callback_param;" X/ y! c% l  R2 h. c! N+ C6 y
  17.         timer_list[i].timer_flag = flag;
    1 u; _; ^- E- d( x( O8 k( O
  18.         return i;
    1 `  C9 t! j1 t% p8 D. M
  19.     }
    9 Y) w3 x* ^7 `4 r; a
  20.     $ L, }  r. d( V& a
  21.     return -1;
    ! J2 E6 s$ n5 N. D
  22. }
复制代码

. Z0 j3 m$ G: C: F/ d6 [8 W6 {6 L7 w
5 A* k1 s/ a5 V* s: n1 B; X
  1. int ifs_stmr_delete(ifs_stmr_handle handle)
      U/ H, B6 a* }2 L4 c2 Z4 {8 G
  2. {
      l4 ?* O: s; H
  3.     int i = (int)handle;
    % r0 M& X& X' k- g$ Z( y( y8 l
  4.    
    " U2 s# ^  ]( B( ]% h" l- b
  5.     if (i >= SOFT_TIMERS_MAX || i < 0) return -1;
    2 S; l% q& A. {6 L% |
  6.     timer_list[i].opt.is_alive = 0;
    0 @7 O( E5 P: u- D/ U! W" @% x# g
  7.     timer_list[i].opt.is_active = 0;
    ) j4 j7 m: W1 V) m: b
  8.     timer_list[i].timer_count = 0;
    $ X/ D4 z$ C' ^, k" u5 V
  9.     timer_list[i].time_out = 0;: Q% v5 F0 n0 Z# ^
  10.     timer_list[i].time_out_callback = NULL;- U# |: S$ P+ E* m
  11.     timer_list[i].param = NULL;
    8 j- R  Z3 U1 I. }; q1 q) t8 d
  12.     timer_list[i].timer_flag = 0;
    / J0 A) n% j7 A( H
  13.     return 0;
    0 f- a! X, Q) Q3 M7 x, p" d+ |' e5 v
  14. }
复制代码

9 y6 P4 S' F7 m6 Q/ R2 h. K& d' H6 z# _/ v7 W" \# X9 e: k6 E
  1. int ifs_stmr_start(ifs_stmr_handle handle)9 c/ g  R- G: [9 R9 @3 Z- E
  2. {7 q7 B; m6 }* S: E+ T8 @
  3.     int i = (int)handle;& t) |- k1 }+ _' E! A& }
  4.     2 l' |! c, y4 f8 t& w/ \
  5.     if (i >= SOFT_TIMERS_MAX || i < 0) return -1;8 e* \. Y/ D( [
  6.     if (!timer_list[i].opt.is_alive) return -1;
    / r8 z; C3 |7 c$ j% ?$ D
  7.    
    5 V+ o6 r- s# K: W# x+ x
  8.     if (timer_list[i].opt.is_active != 1) {
    . S1 K) S" g$ ~3 ^3 ?/ W$ Q$ R
  9.         timer_list[i].timer_count = stmr_ticks;
    ! H1 m; R2 O) W! p( u8 t
  10.         timer_list[i].opt.is_active = 1;7 t0 C* l) Q. `* e4 J( j% S1 u3 O
  11.     }1 d& p& I& p: s! E" N" l7 Z, y
  12.    
    % d0 s1 ?  @$ G
  13.     return 0;; b, S2 }. G  H5 j& m5 _
  14. }
复制代码

0 _% S9 @: Y- U. ]& b. A. k
( ]! q9 O7 _7 j3 Y1 T4 ?  o) G
  1. int ifs_stmr_stop(ifs_stmr_handle handle). ~: E7 b. L5 p4 C7 |, n
  2. {6 I' x6 L4 n4 c+ g* ]9 O
  3.     int i = (int)handle;
    . l5 e( B7 X- ^! v
  4.     . X& v# t' @4 Y" ^% v) b
  5.     if (i >= SOFT_TIMERS_MAX || i < 0) return -1;
    3 O; p2 _6 i" n7 N# R
  6.     if (!timer_list[i].opt.is_alive) return -1;5 s% g- G5 M- A, v
  7.    
    * |. b% z# D4 I7 i6 n" P
  8.     if (timer_list[i].opt.is_active != 0)
    9 l. _; l8 ?( z0 Z. B
  9.         timer_list[i].opt.is_active = 0;
    : }. N7 M$ V2 m7 {# b' o/ {
  10.    
    6 Q5 \0 d! {0 ^
  11.     return 0;
      s2 g6 m" c3 x% M8 d
  12. }
复制代码
- L" E7 ]. L  G
0 @! T/ e1 U0 B
  1. void ifs_stmr_interrupt(void)
    ) }- P" W7 M- Y- ^) g
  2. {; h3 _3 n+ b: p& e$ b, N# p
  3.     stmr_ticks ++;
    4 L7 d  ]5 X2 v: N: r4 d
  4. }
    & f0 q3 E3 a+ g
  5. 8 N" E- V3 i) ?/ `8 J
  6. /*2 f7 Z9 A3 \/ K) `9 d/ ]* u
  7. * !brief soft timer task' h6 A; s& G' m% e1 ?" i' q+ q: W
  8. */  M. ?( x* n  [# U$ z
  9. int ifs_stmr_task(void)0 y. p1 ?8 y  @4 r5 X- ^# D
  10. {7 L, f$ e* E8 q/ L6 q7 G
  11.     ifs_uint8_t i, ret = 0;# C/ N1 T* p( G2 S, W
  12.    
    1 W* Q+ g& I6 N# H  ]
  13.     for (i = 0; i < SOFT_TIMERS_MAX; i ++) {* v' g  N9 G7 `5 i
  14.         if ((timer_list[i].opt.is_alive == 0) ||
    , b( t! F9 v% g% x; X* C3 _
  15.             (timer_list[i].opt.is_active == 0)) {
    6 q! y3 i8 }2 B) s4 D) ]: V% A: m
  16.             continue;+ d, i' \; G% T; P, d/ V) E
  17.                
    4 j/ N3 A1 E; r" n5 h
  18.         }" y( z) `+ `- T; ]( [4 ^
  19.           ~5 b  H! ], O( a: f4 b; K
  20.         if ((stmr_ticks - timer_list[i].timer_count) >= timer_list[i].time_out) {1 U& Z1 i& L3 f! C6 K( N% ^! i
  21.             TMR_CALLBACK(timer_list[i]);
    + l9 c  H" u/ H: U8 I1 _6 j
  22.             if (timer_list[i].timer_flag == IFS_STMR_FLAG_PERIOD) {
    . I3 R. _6 J$ ?: ?/ k  M
  23.                 timer_list[i].timer_count = stmr_ticks;
    $ k) K% }! I" S# Y7 }
  24.             } else if (timer_list[i].timer_flag == IFS_STMR_FLAG_ONESHOT) {    //one shot
    : C- A$ \. @4 r6 \) \
  25.                 timer_list[i].opt.is_active = 0;
    ; F4 c6 _, c9 z: a, x( J
  26.             } else {
    ) J# M0 x4 ^8 E. w
  27.                 timer_list[i].opt.is_alive = 0;$ E/ z$ ~  {+ d2 F$ c2 O4 S
  28.                 timer_list[i].opt.is_active = 0;
      n$ G$ {" e, o- t
  29.             }
    ! V8 ]" ]4 `/ o
  30.         }
    9 r( `& _+ i' E# \' t; ^" ^
  31.         ret++;
      R6 V4 q8 p! z' E3 K
  32.     }
    & N3 b! x  d6 }6 @- ^* v
  33.     return ret;
    + @* ?- G3 t. M$ n
  34. }
复制代码

6 T) P  j* c+ r3 j( q* S9 ]

评分

参与人数 3 ST金币 +60 收起 理由
斜阳__ + 20
zero99 + 20 很给力!
creep + 20 赞一个!

查看全部评分

赞 收藏 4 评论13 发布时间:2018-1-24 18:35

举报

13个回答
andey 回答时间:2018-1-25 09:02:45
提示: 作者被禁止或删除 内容自动屏蔽
zhangxu56726 回答时间:2018-1-25 09:34:54
Inc_brza  给你点赞,  能分享下你的源码吗?大家可以一起用
x5y4z3 回答时间:2018-1-25 09:36:29
这代码简洁有力,调用起来也方便。& W( l; }6 K3 v3 v0 Y3 {$ O; f* u
MrJiu 回答时间:2018-1-25 10:42:53
看起来还可以!!!
anobodykey 回答时间:2018-1-25 10:43:33
顶顶更健康
zero99 回答时间:2018-2-1 09:25:39
感谢支持,已汇总到1月技术原创# M5 j5 [) B( D' _# d
https://www.stmcu.org.cn/module/forum/thread-614550-1-1.html
hudeqis 回答时间:2018-2-2 14:46:02
楼主厉害,前来学习
miaoguoqiang 回答时间:2018-5-22 10:36:40
stmr_tick定义少了一个s   应该是stmr_ticks。
; E% A0 a* W) N) B2 R2 y$ q还有一些定义没有给出。
Inc_brza 回答时间:2018-5-22 11:25:35
╄风、吹不散 发表于 2018-5-22 10:36% q- a* l4 P; V& Q" h9 }
stmr_tick定义少了一个s   应该是stmr_ticks。
% }+ \" t& f& K) J还有一些定义没有给出。
' Z4 I7 a  K% `
这么小得你都看出了,看来时有认真看得呀,哈哈哈哈
, ?" |) ]- q3 R定义全给出了,有啥问题可以说出来一起讨论
miaoguoqiang 回答时间:2018-5-22 11:38:37
已经用起来了。
Inc_brza 回答时间:2018-5-22 18:16:16
╄风、吹不散 发表于 2018-5-22 11:38* F6 ]: u% e$ L, G, a& G" Q- ]5 X. H
已经用起来了。
# B0 u6 R+ a" ?3 ]. D
嗯嗯,有啥好意见尽管提
netman_006 回答时间:2018-8-22 14:51:04
TMR_CALLBACK
* {5 m. L: H  s1 |IFS_STMR_FLAG_PERIOD( c* f1 B, Z1 Z( T" q' P. q: J4 S6 N" Q
IFS_STMR_FLAG_ONESHOT
9 w" j2 S3 o0 t7 V  d& u  l这几个没有定义
hanyc4st 回答时间:2018-8-22 17:01:30
MARKMARK
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版